<!--
@license
Copyright 2018 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS-IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
  <link rel="icon" href="">
  <title>Lighthouse Report</title>
  <style>/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
  Naming convention:

  If a variable is used for a specific component: --{component}-{property name}-{modifier}

  Both {component} and {property name} should be kebab-case. If the target is the entire page,
  use 'report' for the component. The property name should not be abbreviated. Use the
  property name the variable is intended for - if it's used for multiple, a common descriptor
  is fine (ex: 'size' for a variable applied to 'width' and 'height'). If a variable is shared
  across multiple components, either create more variables or just drop the "{component}-"
  part of the name. Append any modifiers at the end (ex: 'big', 'dark').

  For colors: --color-{hue}-{intensity}

  {intensity} is the Material Design tag - 700, A700, etc.
*/
.lh-vars {
  /* Palette using Material Design Colors
   * https://www.materialui.co/colors */
  --color-amber-50: #FFF8E1;
  --color-blue-200: #90CAF9;
  --color-blue-900: #0D47A1;
  --color-blue-A700: #2962FF;
  --color-cyan-500: #00BCD4;
  --color-gray-100: #F5F5F5;
  --color-gray-200: #E0E0E0;
  --color-gray-400: #BDBDBD;
  --color-gray-50: #FAFAFA;
  --color-gray-500: #9E9E9E;
  --color-gray-600: #757575;
  --color-gray-700: #616161;
  --color-gray-800: #424242;
  --color-gray-900: #212121;
  --color-gray: #000000;
  --color-green-700: #018642;
  --color-green: #0CCE6B;
  --color-orange-700: #D04900;
  --color-orange: #FFA400;
  --color-red-700: #EB0F00;
  --color-red: #FF4E42;
  --color-teal-600: #00897B;
  --color-white: #FFFFFF;

  /* Context-specific colors */
  --color-average-secondary: var(--color-orange-700);
  --color-average: var(--color-orange);
  --color-fail-secondary: var(--color-red-700);
  --color-fail: var(--color-red);
  --color-informative: var(--color-blue-900);
  --color-pass-secondary: var(--color-green-700);
  --color-pass: var(--color-green);
  --color-hover: var(--color-gray-50);

  /* Component variables */
  --audit-description-padding-left: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right));
  --audit-explanation-line-height: 16px;
  --audit-group-margin-bottom: 40px;
  --audit-group-padding-vertical: 8px;
  --audit-margin-horizontal: 5px;
  --audit-padding-vertical: 8px;
  --category-header-font-size: 20px;
  --category-padding: 40px;
  --chevron-line-stroke: var(--color-gray-600);
  --chevron-size: 12px;
  --default-padding: 12px;
  --env-item-background-color: var(--color-gray-100);
  --env-item-font-size: 28px;
  --env-item-line-height: 36px;
  --env-item-padding: 10px 0px;
  --env-name-min-width: 220px;
  --footer-padding-vertical: 16px;
  --gauge-circle-size-big: 112px;
  --gauge-circle-size: 80px;
  --gauge-label-font-size-big: 28px;
  --gauge-label-font-size: 20px;
  --gauge-label-line-height-big: 36px;
  --gauge-label-line-height: 26px;
  --gauge-percentage-font-size-big: 38px;
  --gauge-percentage-font-size: 28px;
  --gauge-wrapper-width: 148px;
  --header-line-height: 24px;
  --highlighter-background-color: var(--report-text-color);
  --icon-square-size: calc(var(--score-icon-size) * 0.88);
  --image-preview-size: 48px;
  --metric-toggle-lines-fill: #7F7F7F;
  --metrics-toggle-background-color: var(--color-gray-200);
  --plugin-badge-background-color: var(--color-white);
  --plugin-badge-size-big: calc(var(--gauge-circle-size-big) / 2.7);
  --plugin-badge-size: calc(var(--gauge-circle-size) / 2.7);
  --plugin-icon-size: 65%;
  --pwa-icon-margin: 0 6px 0 -2px;
  --pwa-icon-size: var(--topbar-logo-size);
  --report-background-color: #fff;
  --report-border-color-secondary: #ebebeb;
  --report-font-family-monospace: 'Roboto Mono', 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;
  --report-font-family: Roboto, Helvetica, Arial, sans-serif;
  --report-font-size: 16px;
  --report-line-height: 24px;
  --report-min-width: 400px;
  --report-text-color-secondary: var(--color-gray-800);
  --report-text-color: var(--color-gray-900);
  --report-width: calc(60 * var(--report-font-size));
  --score-container-padding: 8px;
  --score-icon-background-size: 24px;
  --score-icon-margin-left: 4px;
  --score-icon-margin-right: 12px;
  --score-icon-margin: 0 var(--score-icon-margin-right) 0 var(--score-icon-margin-left);
  --score-icon-size: 12px;
  --scores-container-padding: 20px 0 20px 0;
  --scorescale-height: 6px;
  --scorescale-width: 18px;
  --section-padding-vertical: 12px;
  --snippet-background-color: var(--color-gray-50);
  --snippet-color: var(--color-gray-800);
  --sparkline-height: 5px;
  --stackpack-padding-horizontal: 10px;
  --sticky-header-background-color: var(--report-background-color);
  --table-higlight-background-color: hsla(0, 0%, 75%, 0.1);
  --tools-icon-color: var(--color-gray-600);
  --tools-icon-size: var(--score-icon-background-size);
  --topbar-background-color: var(--color-gray-100);
  --topbar-height: 32px;
  --topbar-logo-size: 24px;
  --topbar-padding: 0 8px;
  --toplevel-warning-padding: 22px;

  /* SVGs */
  --plugin-icon-url-dark: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>');
  --plugin-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="%23757575"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>');

  --pass-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>check</title><path fill="%23178239" d="M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z"/></svg>');
  --average-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>info</title><path fill="%23E67700" d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z"/></svg>');
  --fail-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>warn</title><path fill="%23C7221F" d="M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z"/></svg>');

  --pwa-fast-reliable-gray-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23DAE0E3" cx="12" cy="12" r="12"/><path d="M12.3 4l6.3 2.8V11c0 3.88-2.69 7.52-6.3 8.4C8.69 18.52 6 14.89 6 11V6.8L12.3 4zm-.56 12.88l3.3-5.79.04-.08c.05-.1.01-.29-.26-.29h-1.96l.56-3.92h-.56L9.6 12.52c0 .03.07-.12-.03.07-.11.2-.12.37.2.37h1.97l-.56 3.92h.56z" fill="%23FFF"/></g></svg>');
  --pwa-installable-gray-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23DAE0E3" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>');
  --pwa-optimized-gray-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%23DAE0E3" width="24" height="24" rx="12"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/><path d="M5 5h14v14H5z"/></g></svg>');

  --pwa-fast-reliable-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23424242" cx="12" cy="12" r="12"/><path d="M12.3 4l6.3 2.8V11c0 3.88-2.69 7.52-6.3 8.4C8.69 18.52 6 14.89 6 11V6.8L12.3 4zm-.56 12.88l3.3-5.79.04-.08c.05-.1.01-.29-.26-.29h-1.96l.56-3.92h-.56L9.6 12.52c0 .03.07-.12-.03.07-.11.2-.12.37.2.37h1.97l-.56 3.92h.56z" fill="%23FFF"/></g></svg>');
  --pwa-installable-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23424242" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>');
  --pwa-optimized-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%23424242" width="24" height="24" rx="12"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/><path d="M5 5h14v14H5z"/></g></svg>');

  --pwa-fast-reliable-color-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><circle fill="%230CCE6B" cx="12" cy="12" r="12"/><path d="M12 4.3l6.3 2.8v4.2c0 3.88-2.69 7.52-6.3 8.4-3.61-.88-6.3-4.51-6.3-8.4V7.1L12 4.3zm-.56 12.88l3.3-5.79.04-.08c.05-.1.01-.29-.26-.29h-1.96l.56-3.92h-.56L9.3 12.82c0 .03.07-.12-.03.07-.11.2-.12.37.2.37h1.97l-.56 3.92h.56z" fill="%23FFF"/></g></svg>');
  --pwa-installable-color-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><circle fill="%230CCE6B" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>');
  --pwa-optimized-color-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%230CCE6B" width="24" height="24" rx="12"/><path d="M5 5h14v14H5z"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/></g></svg>');
}

@media not print {
  .lh-vars.dark {
    /* Pallete */
    --color-gray-200: var(--color-gray-800);
    --color-gray-400: var(--color-gray-600);
    --color-gray-50: #757575;
    --color-gray-600: var(--color-gray-500);
    --color-green-700: var(--color-green);
    --color-orange-700: var(--color-orange);
    --color-red-700: var(--color-red);
    --color-teal-600: var(--color-cyan-500);

    /* Context-specific colors */
    --color-hover: rgba(0, 0, 0, 0.2);
    --color-informative: var(--color-blue-200);

    /* Component variables */
    --env-item-background-color: var(--color-gray);
    --plugin-badge-background-color: var(--color-gray-800);
    --report-background-color: var(--color-gray-900);
    --report-border-color-secondary: var(--color-gray-200);
    --report-text-color-secondary: var(--color-gray-400);
    --report-text-color: var(--color-gray-100);
    --topbar-background-color: var(--color-gray);

    /* SVGs */
    --plugin-icon-url: var(--plugin-icon-url-dark);
    --pwa-fast-reliable-gray-url: var(--pwa-fast-reliable-gray-url-dark);
    --pwa-installable-gray-url: var(--pwa-installable-gray-url-dark);
    --pwa-optimized-gray-url: var(--pwa-optimized-gray-url-dark);
  }
}

@media only screen and (max-width: 480px) {
  .lh-vars {
    --audit-group-margin-bottom: 20px;
    --category-padding: 24px;
    --env-name-min-width: 120px;
    --gauge-circle-size-big: 96px;
    --gauge-circle-size: 72px;
    --gauge-label-font-size-big: 22px;
    --gauge-label-font-size: 14px;
    --gauge-label-line-height-big: 26px;
    --gauge-label-line-height: 20px;
    --gauge-percentage-font-size-big: 34px;
    --gauge-percentage-font-size: 26px;
    --gauge-wrapper-width: 112px;
    --header-padding: 16px 0 16px 0;
    --image-preview-size: 24px;
    --plugin-icon-size: 75%;
    --pwa-icon-margin: 0 7px 0 -3px;
    --report-font-size: 14px;
    --report-line-height: 20px;
    --score-icon-margin-left: 2px;
    --score-icon-size: 10px;
    --topbar-height: 28px;
    --topbar-logo-size: 20px;
  }

  /* Not enough space to adequately show the relative savings bars. */
  .lh-sparkline {
    display: none;
  }
}

.lh-vars.lh-devtools {
  --audit-explanation-line-height: 14px;
  --audit-group-margin-bottom: 20px;
  --audit-group-padding-vertical: 12px;
  --audit-padding-vertical: 4px;
  --category-header-font-size: 16px;
  --category-padding: 12px;
  --default-padding: 12px;
  --env-name-min-width: 120px;
  --footer-padding-vertical: 8px;
  --gauge-circle-size-big: 72px;
  --gauge-circle-size: 64px;
  --gauge-label-font-size-big: 22px;
  --gauge-label-font-size: 14px;
  --gauge-label-line-height-big: 26px;
  --gauge-label-line-height: 20px;
  --gauge-percentage-font-size-big: 34px;
  --gauge-percentage-font-size: 26px;
  --gauge-wrapper-width: 97px;
  --header-line-height: 20px;
  --header-padding: 16px 0 16px 0;
  --plugin-icon-size: 75%;
  --pwa-icon-margin: 0 7px 0 -3px;
  --report-font-family-monospace: 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;
  --report-font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;
  --report-font-size: 12px;
  --report-line-height: 20px;
  --score-icon-margin-left: 2px;
  --score-icon-size: 10px;
  --section-padding-vertical: 8px;
}

.lh-devtools.lh-root {
  height: 100%;
}
.lh-devtools.lh-root img {
  /* Override devtools default 'min-width: 0' so svg without size in a flexbox isn't collapsed. */
  min-width: auto;
}
.lh-devtools .lh-container {
  overflow-y: scroll;
  height: calc(100% - var(--topbar-height));
}
@media print {
  .lh-devtools .lh-container {
    overflow: unset;
  }
}
.lh-devtools .lh-sticky-header {
  /* This is normally the height of the topbar, but we want it to stick to the top of our scroll container .lh-container` */
  top: 0;
}

@keyframes fadeIn {
  0% { opacity: 0;}
  100% { opacity: 0.6;}
}

.lh-root *, .lh-root *::before, .lh-root *::after {
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
}

.lh-root {
  font-family: var(--report-font-family);
  font-size: var(--report-font-size);
  margin: 0;
  line-height: var(--report-line-height);
  background: var(--report-background-color);
  scroll-behavior: smooth;
  color: var(--report-text-color);
}

.lh-root :focus {
    outline: -webkit-focus-ring-color auto 3px;
}
.lh-root summary:focus {
    outline: none;
    box-shadow: 0 0 0 1px hsl(217, 89%, 61%);
}

.lh-root [hidden] {
  display: none !important;
}

.lh-root details > summary {
  cursor: pointer;
}

.lh-container {
  /*
  Text wrapping in the report is so much FUN!
  We have a `word-break: break-word;` globally here to prevent a few common scenarios, namely
  long non-breakable text (usually URLs) found in:
    1. The footer
    2. .lh-node (outerHTML)
    3. .lh-code

  With that sorted, the next challenge is appropriate column sizing and text wrapping inside our
  .lh-details tables. Even more fun.
    * We don't want table headers ("Potential Savings (ms)") to wrap or their column values, but
    we'd be happy for the URL column to wrap if the URLs are particularly long.
    * We want the narrow columns to remain narrow, providing the most column width for URL
    * We don't want the table to extend past 100% width.
    * Long URLs in the URL column can wrap. Util.getURLDisplayName maxes them out at 64 characters,
      but they do not get any overflow:ellipsis treatment.
  */
  word-break: break-word;
}

.lh-audit-group a,
.lh-category-header__description a,
.lh-audit__description a,
.lh-footer a {
  color: var(--color-informative);
}

.lh-audit__description, .lh-audit__stackpack {
  --inner-audit-padding-right: var(--stackpack-padding-horizontal);
  padding-left: var(--audit-description-padding-left);
  padding-right: var(--inner-audit-padding-right);
  padding-top: 8px;
  padding-bottom: 8px;
}

.lh-details {
  font-size: var(--report-font-size);
  margin-top: var(--default-padding);
  margin-bottom: var(--default-padding);
  margin-left: var(--audit-description-padding-left);
  /* whatever the .lh-details side margins are */
  width: 100%;
}

.lh-details.flex .lh-code {
  max-width: 70%;
}

.lh-audit__stackpack {
  display: flex;
  align-items: center;
}

.lh-audit__stackpack__img {
  max-width: 50px;
  margin-right: var(--default-padding)
}

/* Report header */

.report-icon {
  opacity: 0.7;
}
.report-icon:hover {
  opacity: 1;
}
.report-icon[disabled] {
  opacity: 0.3;
  pointer-events: none;
}

.report-icon--print {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/><path fill="none" d="M0 0h24v24H0z"/></svg>');
}
.report-icon--copy {
  background-image: url('data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>');
}
.report-icon--open {
  background-image: url('data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></svg>');
}
.report-icon--download {
  background-image: url('data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
}
.report-icon--dark {
  background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 100 125"><path d="M50 23.587c-16.27 0-22.799 12.574-22.799 21.417 0 12.917 10.117 22.451 12.436 32.471h20.726c2.32-10.02 12.436-19.554 12.436-32.471 0-8.843-6.528-21.417-22.799-21.417zM39.637 87.161c0 3.001 1.18 4.181 4.181 4.181h.426l.41 1.231C45.278 94.449 46.042 95 48.019 95h3.963c1.978 0 2.74-.551 3.365-2.427l.409-1.231h.427c3.002 0 4.18-1.18 4.18-4.181V80.91H39.637v6.251zM50 18.265c1.26 0 2.072-.814 2.072-2.073v-9.12C52.072 5.813 51.26 5 50 5c-1.259 0-2.072.813-2.072 2.073v9.12c0 1.259.813 2.072 2.072 2.072zM68.313 23.727c.994.774 2.135.634 2.91-.357l5.614-7.187c.776-.992.636-2.135-.356-2.909-.992-.776-2.135-.636-2.91.357l-5.613 7.186c-.778.993-.636 2.135.355 2.91zM91.157 36.373c-.306-1.222-1.291-1.815-2.513-1.51l-8.85 2.207c-1.222.305-1.814 1.29-1.51 2.512.305 1.223 1.291 1.814 2.513 1.51l8.849-2.206c1.223-.305 1.816-1.291 1.511-2.513zM86.757 60.48l-8.331-3.709c-1.15-.512-2.225-.099-2.736 1.052-.512 1.151-.1 2.224 1.051 2.737l8.33 3.707c1.15.514 2.225.101 2.736-1.05.513-1.149.1-2.223-1.05-2.737zM28.779 23.37c.775.992 1.917 1.131 2.909.357.992-.776 1.132-1.917.357-2.91l-5.615-7.186c-.775-.992-1.917-1.132-2.909-.357s-1.131 1.917-.356 2.909l5.614 7.187zM21.715 39.583c.305-1.223-.288-2.208-1.51-2.513l-8.849-2.207c-1.222-.303-2.208.289-2.513 1.511-.303 1.222.288 2.207 1.511 2.512l8.848 2.206c1.222.304 2.208-.287 2.513-1.509zM21.575 56.771l-8.331 3.711c-1.151.511-1.563 1.586-1.05 2.735.511 1.151 1.586 1.563 2.736 1.052l8.331-3.711c1.151-.511 1.563-1.586 1.05-2.735-.512-1.15-1.585-1.562-2.736-1.052z"/></svg>');
}

/* Node */
.lh-node__snippet {
  font-family: var(--report-font-family-monospace);
  color: var(--color-teal-600);
  font-size: 12px;
  line-height: 1.5em;
}

/* Score */

.lh-audit__score-icon {
  width: var(--score-icon-size);
  height: var(--score-icon-size);
  margin: var(--score-icon-margin);
}

.lh-audit--pass .lh-audit__display-text {
  color: var(--color-pass-secondary);
}
.lh-audit--pass .lh-audit__score-icon {
  border-radius: 100%;
  background: var(--color-pass);
}

.lh-audit--average .lh-audit__display-text {
  color: var(--color-average-secondary);
}
.lh-audit--average .lh-audit__score-icon {
  background: var(--color-average);
  width: var(--icon-square-size);
  height: var(--icon-square-size);
}

.lh-audit--fail .lh-audit__display-text {
  color: var(--color-fail-secondary);
}
.lh-audit--fail .lh-audit__score-icon,
.lh-audit--error .lh-audit__score-icon {
  border-left: calc(var(--score-icon-size) / 2) solid transparent;
  border-right: calc(var(--score-icon-size) / 2) solid transparent;
  border-bottom: var(--score-icon-size) solid var(--color-fail);
}

.lh-audit--manual .lh-audit__display-text,
.lh-audit--notapplicable .lh-audit__display-text {
  color: var(--color-gray-600);
}
.lh-audit--manual .lh-audit__score-icon,
.lh-audit--notapplicable .lh-audit__score-icon {
  border-radius: 100%;
  background: var(--color-gray-400);
}

.lh-audit--informative .lh-audit__display-text {
  color: var(--color-gray-600);
}

.lh-audit--informative .lh-audit__score-icon {
  border: none;
  border-radius: 100%;
  background: var(--color-gray-400);
}

.lh-audit__description,
.lh-audit__stackpack {
  color: var(--report-text-color-secondary);
}
.lh-category-header__description  {
  font-size: var(--report-font-size);
  text-align: center;
  margin: 0px auto;
  max-width: 400px;
}


.lh-audit__display-text,
.lh-load-opportunity__sparkline,
.lh-chevron-container {
  margin: 0 var(--audit-margin-horizontal);
}
.lh-chevron-container {
  margin-right: 0;
}

.lh-audit__title-and-text {
  flex: 1;
}

/* Prepend display text with em dash separator. But not in Opportunities. */
.lh-audit__display-text:not(:empty):before {
  content: '—';
  margin-right: var(--audit-margin-horizontal);
}
.lh-audit-group.lh-audit-group--load-opportunities .lh-audit__display-text:not(:empty):before {
  display: none;
}

/* Expandable Details (Audit Groups, Audits) */
.lh-audit__header {
  display: flex;
  align-items: center;
  font-weight: 500;
  padding: var(--audit-padding-vertical) 0;
}

.lh-audit--load-opportunity .lh-audit__header {
  display: block;
}

.lh-audit__header:hover {
  background-color: var(--color-hover);
}

/* Hide the expandable arrow icon, three ways: via the CSS Counter Styles spec, for webkit/blink browsers, hiding the polyfilled icon */
/* https://github.com/javan/details-element-polyfill/blob/master/src/details-element-polyfill/polyfill.sass */
.lh-audit-group > summary,
.lh-expandable-details > summary {
  list-style-type: none;
}
.lh-audit-group > summary::-webkit-details-marker,
.lh-expandable-details > summary::-webkit-details-marker {
  display: none;
}
.lh-audit-group > summary:before,
.lh-expandable-details > summary:before {
  display: none;
}


/* Perf Metric */

.lh-columns {
  display: flex;
  width: 100%;
}
@media screen and (max-width: 640px) {
  .lh-columns {
    flex-wrap: wrap;

  }
}

.lh-column {
  flex: 1;
}
.lh-column:first-of-type {
  margin-right: 24px;
}

@media screen and (max-width: 800px) {
  .lh-column:first-of-type {
    margin-right: 8px;
  }
}
@media screen and (max-width: 640px) {
  .lh-column {
    flex-basis: 100%;
  }
  .lh-column:first-of-type {
    margin-right: 0px;
  }
  .lh-column:first-of-type .lh-metric:last-of-type {
    border-bottom: 0;
  }
}


.lh-metric {
  border-bottom: 1px solid var(--report-border-color-secondary);
}
.lh-metric:first-of-type {
  border-top: 1px solid var(--report-border-color-secondary);
}

.lh-metric__innerwrap {
  display: grid;
  grid-template-columns: var(--audit-description-padding-left) 10fr 3fr;
  align-items: center;
  padding: 10px 0;
}

.lh-metric__details {
  order: -1;
}

.lh-metric__title {
  flex: 1;
  font-weight: 500;
}

.lh-metrics__disclaimer {
  color: var(--color-gray-600);
  margin: var(--section-padding-vertical) 0;
}
.lh-metrics__disclaimer a {
  color: var(--color-gray-700);
}

.lh-metric__description {
  display: none;
  grid-column-start: 2;
  grid-column-end: 3;
  color: var(--report-text-color-secondary);
}

.lh-metric__value {
  white-space: nowrap; /* No wrapping between metric value and the icon */
  font-weight: 500;
  justify-self: end;
}

/* No-JS toggle switch */
/* Keep this selector sync'd w/ `magicSelector` in report-ui-features-test.js */
 .lh-metrics-toggle__input:checked ~ .lh-columns .lh-metric__description {
  display: block;
}

.lh-metrics-toggle__input {
  cursor: pointer;
  opacity: 0;
  position: absolute;
  right: 0;
  width: 74px;
  height: 28px;
  top: -3px;
}
.lh-metrics-toggle__label {
  display: flex;
  background-color: #eee;
  border-radius: 20px;
  overflow: hidden;
  position: absolute;
  right: 0;
  top: -3px;
  pointer-events: none;
}
.lh-metrics-toggle__input:focus + label {
  outline: -webkit-focus-ring-color auto 3px;
}
.lh-metrics-toggle__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px 5px;
  width: 50%;
  height: 28px;
}
.lh-metrics-toggle__input:not(:checked) + label .lh-metrics-toggle__icon--less,
.lh-metrics-toggle__input:checked + label .lh-metrics-toggle__icon--more {
  background-color: var(--color-blue-A700);
  --metric-toggle-lines-fill: var(--color-white);
}
.lh-metrics-toggle__lines {
  fill: var(--metric-toggle-lines-fill);
}

.lh-metrics-toggle__label  {
  background-color: var(--metrics-toggle-background-color);
}

.lh-metrics-toggle__label .lh-metrics-toggle__icon--less {
  padding-left: 8px;
}
.lh-metrics-toggle__label .lh-metrics-toggle__icon--more {
  padding-right: 8px;
}

/* Pushes the metric description toggle button to the right. */
.lh-audit-group--metrics .lh-audit-group__header {
  display: flex;
}
.lh-audit-group--metrics .lh-audit-group__header span.lh-audit-group__title {
  flex: 1;
}

.lh-metric .lh-metric__innerwrap::before {
  content: '';
  width: var(--score-icon-size);
  height: var(--score-icon-size);
  display: inline-block;
  margin: var(--score-icon-margin);
}

.lh-metric--pass .lh-metric__value {
  color: var(--color-pass-secondary);
}
.lh-metric--pass .lh-metric__innerwrap::before {
  border-radius: 100%;
  background: var(--color-pass);
}

.lh-metric--average .lh-metric__value {
  color: var(--color-average-secondary);
}
.lh-metric--average .lh-metric__innerwrap::before {
  background: var(--color-average);
  width: var(--icon-square-size);
  height: var(--icon-square-size);
}

.lh-metric--fail .lh-metric__value {
  color: var(--color-fail-secondary);
}
.lh-metric--fail .lh-metric__innerwrap::before,
.lh-metric--error .lh-metric__innerwrap::before {
  border-left: calc(var(--score-icon-size) / 2) solid transparent;
  border-right: calc(var(--score-icon-size) / 2) solid transparent;
  border-bottom: var(--score-icon-size) solid var(--color-fail);
}

.lh-metric--error .lh-metric__value,
.lh-metric--error .lh-metric__description {
  color: var(--color-fail-secondary);
}

/* Perf load opportunity */

.lh-load-opportunity__cols {
  display: flex;
  align-items: flex-start;
}

.lh-load-opportunity__header .lh-load-opportunity__col {
  color: var(--color-gray-600);
  display: unset;
  line-height: calc(2.3 * var(--report-font-size));
}

.lh-load-opportunity__col {
  display: flex;
}

.lh-load-opportunity__col--one {
  flex: 5;
  align-items: center;
  margin-right: 2px;
}
.lh-load-opportunity__col--two {
  flex: 4;
  text-align: right;
}

.lh-audit--load-opportunity .lh-audit__display-text {
  text-align: right;
  flex: 0 0 calc(3 * var(--report-font-size));
}


/* Sparkline */

.lh-load-opportunity__sparkline {
  flex: 1;
  margin-top: calc((var(--report-line-height) - var(--sparkline-height)) / 2);
}

.lh-sparkline {
  height: var(--sparkline-height);
  width: 100%;
}

.lh-sparkline__bar {
  height: 100%;
  float: right;
}

.lh-audit--pass .lh-sparkline__bar {
  background: var(--color-pass);
}

.lh-audit--average .lh-sparkline__bar {
  background: var(--color-average);
}

.lh-audit--fail .lh-sparkline__bar {
  background: var(--color-fail);
}



/* Filmstrip */

.lh-filmstrip-container {
  /* smaller gap between metrics and filmstrip */
  margin: -8px auto 0 auto;
}

.lh-filmstrip {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  padding-bottom: var(--default-padding);
}

.lh-filmstrip__frame {
  text-align: right;
  position: relative;
}

.lh-filmstrip__thumbnail {
  border: 1px solid var(--report-border-color-secondary);
  max-height: 100px;
  max-width: 60px;
}

@media screen and (max-width: 750px) {
  .lh-filmstrip {
    flex-wrap: wrap;
  }
  .lh-filmstrip__frame {
    width: 20%;
    margin-bottom: 5px;
  }
  .lh-filmstrip__thumbnail {
    display: block;
    margin: auto;
  }
}

/* Audit */

.lh-audit {
  border-bottom: 1px solid var(--report-border-color-secondary);
}

/* Apply border-top to just the first audit. */
.lh-audit {
  border-top: 1px solid var(--report-border-color-secondary);
}
.lh-audit ~ .lh-audit {
  border-top: none;
}


.lh-audit--error .lh-audit__display-text {
  color: var(--color-fail);
}

/* Audit Group */

.lh-audit-group {
  margin-bottom: var(--audit-group-margin-bottom);
  position: relative;
}

.lh-audit-group__header::before {
  /* By default, groups don't get an icon */
  content: none;
  width: var(--pwa-icon-size);
  height: var(--pwa-icon-size);
  margin: var(--pwa-icon-margin);
  display: inline-block;
  vertical-align: middle;
}

/* Style the "over budget" columns red. */
.lh-audit-group--budgets .lh-table tbody tr td:nth-child(4),
.lh-audit-group--budgets .lh-table tbody tr td:nth-child(5){
  color: var(--color-red-700);
}

/* Align the "over budget request count" text to be close to the "over budget bytes" column. */
.lh-audit-group--budgets .lh-table tbody tr td:nth-child(4){
  text-align: right;
}

.lh-audit-group--budgets .lh-table {
  width: 100%;
}

.lh-audit-group--pwa-fast-reliable .lh-audit-group__header::before {
  content: '';
  background-image: var(--pwa-fast-reliable-gray-url);
}
.lh-audit-group--pwa-installable .lh-audit-group__header::before {
  content: '';
  background-image: var(--pwa-installable-gray-url);
}
.lh-audit-group--pwa-optimized .lh-audit-group__header::before {
  content: '';
  background-image: var(--pwa-optimized-gray-url);
}
.lh-audit-group--pwa-fast-reliable.lh-badged .lh-audit-group__header::before {
  background-image: var(--pwa-fast-reliable-color-url);
}
.lh-audit-group--pwa-installable.lh-badged .lh-audit-group__header::before {
  background-image: var(--pwa-installable-color-url);
}
.lh-audit-group--pwa-optimized.lh-badged .lh-audit-group__header::before {
  background-image: var(--pwa-optimized-color-url);
}

.lh-audit-group--metrics .lh-audit-group__summary {
  margin-top: 0;
  margin-bottom: 0;
}

.lh-audit-group__summary {
  display: flex;
  justify-content: space-between;
  margin-top: calc(var(--category-padding) * 1.5);
  margin-bottom: var(--category-padding);
}

.lh-audit-group__itemcount {
  color: var(--color-gray-600);
  font-weight: bold;
}
.lh-audit-group__header .lh-chevron {
  margin-top: calc((var(--report-line-height) - 5px) / 2);
}

.lh-audit-group__header {
  font-size: var(--report-font-size);
  margin: 0 0 var(--audit-group-padding-vertical);
  /* When the header takes 100% width, the chevron becomes small. */
  max-width: calc(100% - var(--chevron-size));
}
/* max-width makes the metric toggle not flush. metrics doesn't have a chevron so unset. */
.lh-audit-group--metrics .lh-audit-group__header {
  max-width: unset;
}

.lh-audit-group__header span.lh-audit-group__title {
  font-weight: bold;
}

.lh-audit-group__header span.lh-audit-group__itemcount {
  font-weight: bold;
  color: var(--color-gray-600);
}

.lh-audit-group__header span.lh-audit-group__description {
  font-weight: 500;
  color: var(--color-gray-600);
}
.lh-audit-group__header span.lh-audit-group__description::before {
  content: '—';
  margin: 0px var(--audit-margin-horizontal);
}

.lh-clump > .lh-audit-group__header,
.lh-audit-group--diagnostics .lh-audit-group__header,
.lh-audit-group--load-opportunities .lh-audit-group__header,
.lh-audit-group--metrics .lh-audit-group__header,
.lh-audit-group--pwa-fast-reliable .lh-audit-group__header,
.lh-audit-group--pwa-installable .lh-audit-group__header,
.lh-audit-group--pwa-optimized .lh-audit-group__header {
  margin-top: var(--audit-group-padding-vertical);
}

.lh-audit-explanation {
  margin: var(--audit-padding-vertical) 0 calc(var(--audit-padding-vertical) / 2) var(--audit-margin-horizontal);
  line-height: var(--audit-explanation-line-height);
  display: inline-block;
}

.lh-audit--fail .lh-audit-explanation {
  color: var(--color-fail);
}

/* Report */
.lh-list > div:not(:last-child) {
  padding-bottom: 20px;
}

.lh-header-container {
  display: block;
  margin: 0 auto;
  position: relative;
  word-wrap: break-word;
}

.lh-report {
  min-width: var(--report-min-width);
}

.lh-exception {
  font-size: large;
}

.lh-code {
  white-space: normal;
  margin-top: 0;
  font-size: 85%;
}

.lh-warnings {
  --item-margin: calc(var(--report-line-height) / 6);
  color: var(--color-average);
  margin: var(--audit-padding-vertical) 0;
  padding: calc(var(--audit-padding-vertical) / 2) var(--audit-padding-vertical);
}
.lh-warnings span {
  font-weight: bold;
}

.lh-warnings--toplevel {
  --item-margin: calc(var(--header-line-height) / 4);
  color: var(--report-text-color-secondary);
  margin-left: auto;
  margin-right: auto;
  max-width: calc(var(--report-width) - var(--category-padding) * 2);
  background-color: var(--color-amber-50);
  padding: var(--toplevel-warning-padding);
}

.lh-warnings ul {
  padding-left: calc(var(--category-padding) * 2);
  margin: 0;
}
.lh-warnings li {
  margin: var(--item-margin) 0;
}
.lh-warnings li:last-of-type {
  margin-bottom: 0;
}

.lh-scores-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.lh-scores-header__solo {
  padding: 0;
  border: 0;
}

/* Gauge */

.lh-gauge__wrapper--pass {
  color: var(--color-pass);
  fill: var(--color-pass);
  stroke: var(--color-pass);
}

.lh-gauge__wrapper--average {
  color: var(--color-average);
  fill: var(--color-average);
  stroke: var(--color-average);
}

.lh-gauge__wrapper--fail {
  color: var(--color-fail);
  fill: var(--color-fail);
  stroke: var(--color-fail);
}

.lh-gauge {
  stroke-linecap: round;
  width: var(--gauge-circle-size);
  height: var(--gauge-circle-size);
}

.lh-category .lh-gauge {
  --gauge-circle-size: var(--gauge-circle-size-big);
}

.lh-gauge-base {
    opacity: 0.1;
    stroke: var(--circle-background);
    stroke-width: var(--circle-border-width);
}

.lh-gauge-arc {
    fill: none;
    stroke: var(--circle-color);
    stroke-width: var(--circle-border-width);
    animation: load-gauge var(--transition-length) ease forwards;
    animation-delay: 250ms;
}

.lh-gauge__svg-wrapper {
  position: relative;
  height: var(--gauge-circle-size);
}
.lh-category .lh-gauge__svg-wrapper {
  --gauge-circle-size: var(--gauge-circle-size-big);
}

/* The plugin badge overlay */
.lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {
  width: var(--plugin-badge-size);
  height: var(--plugin-badge-size);
  background-color: var(--plugin-badge-background-color);
  background-image: var(--plugin-icon-url);
  background-repeat: no-repeat;
  background-size: var(--plugin-icon-size);
  background-position: 58% 50%;
  content: "";
  position: absolute;
  right: -6px;
  bottom: 0px;
  display: block;
  z-index: 100;
  box-shadow: 0 0 4px rgba(0,0,0,.2);
  border-radius: 25%;
}
.lh-category .lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {
  width: var(--plugin-badge-size-big);
  height: var(--plugin-badge-size-big);
}

@keyframes load-gauge {
  from { stroke-dasharray: 0 352; }
}

.lh-gauge__percentage {
  width: 100%;
  height: var(--gauge-circle-size);
  position: absolute;
  font-family: var(--report-font-family-monospace);
  font-size: calc(var(--gauge-circle-size) * 0.34 + 1.3px);
  line-height: 0;
  text-align: center;
  top: calc(var(--score-container-padding) + var(--gauge-circle-size) / 2);
}

.lh-category .lh-gauge__percentage {
  --gauge-circle-size: var(--gauge-circle-size-big);
  --gauge-percentage-font-size: var(--gauge-percentage-font-size-big);
}

.lh-gauge__wrapper {
  position: relative;
  display: flex;
  align-items: center;
  flex-direction: column;
  text-decoration: none;
  padding: var(--score-container-padding);

  --circle-border-width: 8;
  --transition-length: 1s;

  /* Contain the layout style paint & layers during animation*/
  contain: content;
  will-change: opacity; /* Only using for layer promotion */
}

.lh-gauge__label {
  font-size: var(--gauge-label-font-size);
  line-height: var(--gauge-label-line-height);
  margin-top: 10px;
  text-align: center;
  color: var(--report-text-color);
}

/* TODO(#8185) use more BEM (.lh-gauge__label--big) instead of relying on descendant selector */
.lh-category .lh-gauge__label {
  --gauge-label-font-size: var(--gauge-label-font-size-big);
  --gauge-label-line-height: var(--gauge-label-line-height-big);
  margin-top: 14px;
}


.lh-scores-header .lh-gauge__wrapper,
.lh-scores-header .lh-gauge--pwa__wrapper,
.lh-sticky-header .lh-gauge__wrapper,
.lh-sticky-header .lh-gauge--pwa__wrapper {
  width: var(--gauge-wrapper-width);
}

.lh-scorescale {
  display: inline-flex;
  margin: 12px auto 0 auto;
  border: 1px solid var(--color-gray-200);
  border-radius: 20px;
  padding: 8px 8px;
}

.lh-scorescale-range {
  display: flex;
  align-items: center;
  margin: 0 12px;
  font-family: var(--report-font-family-monospace);
  white-space: nowrap;
}

.lh-scorescale-range::before {
  content: '';
  width: var(--scorescale-width);
  height: var(--scorescale-height);
  border-radius: 10px;
  display: block;
  margin-right: 10px;
}

.lh-scorescale-range--pass::before {
  background-color: var(--color-pass);
}

.lh-scorescale-range--average::before {
  background-color: var(--color-average);
}

.lh-scorescale-range--fail::before {
  background-color: var(--color-fail);
}

/* Hide category score gauages if it's a single category report */
.lh-header--solo-category .lh-scores-wrapper {
  display: none;
}


.lh-categories {
  width: 100%;
  overflow: hidden;
}

.lh-category {
  padding: var(--category-padding);
  max-width: var(--report-width);
  margin: 0 auto;
}

.lh-category-wrapper {
  border-bottom: 1px solid var(--color-gray-200);
}

.lh-category-wrapper:first-of-type {
  border-top: 1px solid var(--color-gray-200);
}

/* section hash link jump should preserve fixed header
   https://css-tricks.com/hash-tag-links-padding/
*/
.lh-category > .lh-permalink {
  --sticky-header-height: calc(var(--gauge-circle-size) + var(--score-container-padding) * 2);
  --topbar-plus-header: calc(var(--topbar-height) + var(--sticky-header-height));
  margin-top: calc(var(--topbar-plus-header) * -1);
  padding-bottom: var(--topbar-plus-header);
  display: block;
  visibility: hidden;
}

.lh-category-header {
  font-size: var(--category-header-font-size);
  min-height: var(--gauge-circle-size);
  margin-bottom: var(--section-padding-vertical);
}

.lh-category-header .lh-score__gauge {
  max-width: 400px;
  width: auto;
  margin: 0px auto;
}

.lh-category-header .lh-audit__title {
  font-size: var(--category-header-font-size);
  line-height: var(--header-line-height);
}

#lh-log {
  position: fixed;
  background-color: #323232;
  color: #fff;
  min-height: 48px;
  min-width: 288px;
  padding: 16px 24px;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
  border-radius: 2px;
  margin: 12px;
  font-size: 14px;
  cursor: default;
  transition: transform 0.3s, opacity 0.3s;
  transform: translateY(100px);
  opacity: 0;
  bottom: 0;
  left: 0;
  z-index: 3;
}

#lh-log.show {
  opacity: 1;
  transform: translateY(0);
}

/* 964 fits the min-width of the filmstrip */
@media screen and (max-width: 964px) {
  .lh-report {
    margin-left: 0;
    width: 100%;
  }
}

@media print {
  body {
    -webkit-print-color-adjust: exact; /* print background colors */
  }
  .lh-container {
    display: block;
  }
  .lh-report {
    margin-left: 0;
    padding-top: 0;
  }
  .lh-categories {
    margin-top: 0;
  }
}

.lh-table {
  border-collapse: collapse;
  /* Can't assign padding to table, so shorten the width instead. */
  width: calc(100% - var(--audit-description-padding-left));
}

.lh-table thead th {
  font-weight: normal;
  color: var(--color-gray-600);
  /* See text-wrapping comment on .lh-container. */
  word-break: normal;
}

.lh-table tbody tr:nth-child(odd) {
  background-color: var(--table-higlight-background-color);
}

.lh-table th,
.lh-table td {
  padding: 8px 6px;
}
.lh-table th:first-child {
  padding-left: 0;
}
.lh-table th:last-child {
  padding-right: 0;
}

/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */
.lh-table-column--text,
.lh-table-column--url,
/* .lh-table-column--thumbnail, */
/* .lh-table-column--empty,*/
.lh-table-column--code,
.lh-table-column--node {
  text-align: left;
}

.lh-table-column--bytes,
.lh-table-column--timespanMs,
.lh-table-column--ms,
.lh-table-column--numeric {
  text-align: right;
  word-break: normal;
}



.lh-table .lh-table-column--thumbnail {
  width: var(--image-preview-size);
  padding: 0;
}

.lh-table-column--url {
  min-width: 250px;
}

/* Keep columns narrow if they follow the URL column */
/* 12% was determined to be a decent narrow width, but wide enough for column headings */
.lh-table-column--url + th.lh-table-column--bytes,
.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes,
.lh-table-column--url + .lh-table-column--ms,
.lh-table-column--url + .lh-table-column--ms + th.lh-table-column--bytes,
.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--timespanMs {
  width: 12%;
}


.lh-text__url-host {
  display: inline;
}

.lh-text__url-host {
  margin-left: calc(var(--report-font-size) / 2);
  opacity: 0.6;
  font-size: 90%
}

.lh-thumbnail {
  object-fit: cover;
  width: var(--image-preview-size);
  height: var(--image-preview-size);
  display: block;
}

.lh-unknown pre {
  overflow: scroll;
  border: solid 1px var(--color-gray-200);
}

.lh-text__url > a {
  color: inherit;
  text-decoration: none;
}

.lh-text__url > a:hover {
  text-decoration: underline dotted #999;
}

/* Chevron
   https://codepen.io/paulirish/pen/LmzEmK
 */
.lh-chevron {
  --chevron-angle: 42deg;
  /* Edge doesn't support transform: rotate(calc(...)), so we define it here */
  --chevron-angle-right: -42deg;
  width: var(--chevron-size);
  height: var(--chevron-size);
  margin-top: calc((var(--report-line-height) - 12px) / 2);
}

.lh-chevron__lines {
  transition: transform 0.4s;
  transform: translateY(var(--report-line-height));
}
.lh-chevron__line {
 stroke: var(--chevron-line-stroke);
 stroke-width: var(--chevron-size);
 stroke-linecap: square;
 transform-origin: 50%;
 transform: rotate(var(--chevron-angle));
 transition: transform 300ms, stroke 300ms;
}

.lh-audit-group > summary > .lh-audit-group__summary > .lh-chevron .lh-chevron__line-right,
.lh-audit-group[open] > summary > .lh-audit-group__summary > .lh-chevron .lh-chevron__line-left,
.lh-audit > .lh-expandable-details .lh-chevron__line-right,
.lh-audit > .lh-expandable-details[open] .lh-chevron__line-left {
 transform: rotate(var(--chevron-angle-right));
}

.lh-audit-group[open] > summary > .lh-audit-group__summary > .lh-chevron .lh-chevron__line-right,
.lh-audit > .lh-expandable-details[open] .lh-chevron__line-right {
  transform: rotate(var(--chevron-angle));
}

.lh-audit-group[open] > summary > .lh-audit-group__summary > .lh-chevron .lh-chevron__lines,
.lh-audit > .lh-expandable-details[open] .lh-chevron__lines {
 transform: translateY(calc(var(--chevron-size) * -1));
}



/* Tooltip */
.tooltip-boundary {
  position: relative;
}

.tooltip {
  position: absolute;
  display: none; /* Don't retain these layers when not needed */
  opacity: 0;
  background: #ffffff;
  min-width: 246px;
  max-width: 275px;
  padding: 15px;
  border-radius: 5px;
  text-align: initial;
}
/* shrink tooltips to not be cutoff on left edge of narrow viewports
   45vw is chosen to be ~= width of the left column of metrics
*/
@media screen and (max-width: 535px) {
  .tooltip {
    min-width: 45vw;
    padding: 3vw;
  }
}

.tooltip-boundary:hover {
  background-color: var(--color-hover);
}

.tooltip-boundary:hover .tooltip {
  display: block;
  animation: fadeInTooltip 250ms;
  animation-fill-mode: forwards;
  animation-delay: 850ms;
  bottom: 100%;
  z-index: 1;
  will-change: opacity;
  right: 0;
  pointer-events: none;
}

.tooltip::before {
  content: "";
  border: solid transparent;
  border-bottom-color: #fff;
  border-width: 10px;
  position: absolute;
  bottom: -20px;
  right: 6px;
  transform: rotate(180deg);
  pointer-events: none;
}

@keyframes fadeInTooltip {
  0% { opacity: 0; }
  75% { opacity: 1; }
  100% { opacity: 1;  filter: drop-shadow(1px 0px 1px #aaa) drop-shadow(0px 2px 4px hsla(206, 6%, 25%, 0.15)); pointer-events: auto; }
}
</style>
</head>
<body class="lh-root lh-vars">
  <noscript>Lighthouse report requires JavaScript. Please enable.</noscript>
  <div hidden><!--
@license
Copyright 2018 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS-IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<!-- Lighthouse run warnings -->
<template id="tmpl-lh-warnings--toplevel">
  <div class="lh-warnings lh-warnings--toplevel">
    <strong class="lh-warnings__msg"></strong>
    <ul></ul>
  </div>
</template>

<!-- Lighthouse score scale -->
<template id="tmpl-lh-scorescale">
  <div class="lh-scorescale">
      <span class="lh-scorescale-range lh-scorescale-range--fail">0&ndash;49</span>
      <span class="lh-scorescale-range lh-scorescale-range--average">50&ndash;89</span>
      <span class="lh-scorescale-range lh-scorescale-range--pass">90&ndash;100</span>
  </div>
</template>

<!-- Toggle arrow chevron -->
<template id="tmpl-lh-chevron">
  <svg class="lh-chevron" title="See audits" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 100">
    <g class="lh-chevron__lines">
      <path class="lh-chevron__line lh-chevron__line-left" d="M10 50h40"></path>
      <path class="lh-chevron__line lh-chevron__line-right" d="M90 50H50"></path>
    </g>
  </svg>
</template>

<!-- Lighthouse category header -->
<template id="tmpl-lh-category-header">
  <div class="lh-category-header">
    <div class="lh-score__gauge" role="heading" aria-level="2"></div>
    <div class="lh-category-header__description"></div>
  </div>
</template>

<!-- Lighthouse clump -->
<template id="tmpl-lh-clump">
  <!-- TODO: group classes shouldn't be reused for clumps. -->
  <details class="lh-clump lh-audit-group">
    <summary>
      <div class="lh-audit-group__summary">
        <div class="lh-audit-group__header">
          <span class="lh-audit-group__title"></span>
          <span class="lh-audit-group__itemcount"></span>
          <!-- .lh-audit-group__description will be added here -->
          <!-- .lh-metrics-toggle will be added here -->
        </div>
        <div class=""></div>
      </div>
    </summary>
  </details>
</template>

<!-- Lighthouse metrics toggle -->
<template id="tmpl-lh-metrics-toggle">
  <div class="lh-metrics-toggle">
    <input class="lh-metrics-toggle__input" type="checkbox" id="toggle-metric-descriptions" aria-label="Toggle the display of metric descriptions">
    <label class="lh-metrics-toggle__label" for="toggle-metric-descriptions">
      <div class="lh-metrics-toggle__icon lh-metrics-toggle__icon--less" aria-hidden="true">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
          <path class="lh-metrics-toggle__lines" d="M4 9h16v2H4zm0 4h10v2H4z" />
        </svg>
      </div>
      <div class="lh-metrics-toggle__icon lh-metrics-toggle__icon--more" aria-hidden="true">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
          <path class="lh-metrics-toggle__lines" d="M3 18h12v-2H3v2zM3 6v2h18V6H3zm0 7h18v-2H3v2z" />
        </svg>
      </div>
    </label>
  </div>
</template>

<!-- Lighthouse audit -->
<template id="tmpl-lh-audit">
  <div class="lh-audit">
    <details class="lh-expandable-details">
      <summary>
        <div class="lh-audit__header lh-expandable-details__summary">
          <span class="lh-audit__score-icon"></span>
          <span class="lh-audit__title-and-text">
            <span class="lh-audit__title"></span>
            <span class="lh-audit__display-text"></span>
          </span>
          <div class="lh-chevron-container"></div>
        </div>
      </summary>
      <div class="lh-audit__description"></div>
      <div class="lh-audit__stackpacks"></div>
    </details>
  </div>
</template>

<!-- Lighthouse perf metric -->
<template id="tmpl-lh-metric">
  <div class="lh-metric">
    <div class="lh-metric__innerwrap">
      <span class="lh-metric__title"></span>
      <div class="lh-metric__value"></div>
      <div class="lh-metric__description"></div>
    </div>
  </div>
</template>

<!-- Lighthouse perf opportunity -->
<template id="tmpl-lh-opportunity">
  <div class="lh-audit lh-audit--load-opportunity">
    <details class="lh-expandable-details">
        <summary>
          <div class="lh-audit__header lh-expandable-details__summary">
            <div class="lh-load-opportunity__cols">
              <div class="lh-load-opportunity__col lh-load-opportunity__col--one">
                <span class="lh-audit__score-icon"></span>
                <div class="lh-audit__title"></div>
              </div>
              <div class="lh-load-opportunity__col lh-load-opportunity__col--two">
                <div class="lh-load-opportunity__sparkline">
                  <div class="lh-sparkline"><div class="lh-sparkline__bar"></div></div>
                </div>
                <div class="lh-audit__display-text"></div>
                <div class="lh-chevron-container" title="See resources"></div>
              </div>
            </div>
          </div>
        </summary>
      <div class="lh-audit__description"></div>
      <div class="lh-audit__stackpacks"></div>
    </details>
  </div>
</template>

<!-- Lighthouse perf opportunity header -->
<template id="tmpl-lh-opportunity-header">
  <div class="lh-load-opportunity__header lh-load-opportunity__cols">
    <div class="lh-load-opportunity__col lh-load-opportunity__col--one"></div>
    <div class="lh-load-opportunity__col lh-load-opportunity__col--two"></div>
  </div>
</template>

<!-- Lighthouse score container -->
<template id="tmpl-lh-scores-wrapper">
  <style>
    .lh-scores-container {
      display: flex;
      flex-direction: column;
      padding: var(--scores-container-padding);
      position: relative;
      width: 100%;
    }

    .lh-sticky-header {
      --gauge-circle-size: 36px;
      --plugin-badge-size: 18px;
      --plugin-icon-size: 75%;
      --gauge-wrapper-width: 60px;
      --gauge-percentage-font-size: 13px;
      position: sticky;
      left: 0;
      right: 0;
      top: var(--topbar-height);
      font-weight: 700;
      display: none;
      justify-content: center;
      background-color: var(--sticky-header-background-color);
      border-bottom: 1px solid var(--color-gray-200);
      padding-top: var(--score-container-padding);
      padding-bottom: 4px;
      z-index: 1;
      pointer-events: none;
    }

    .lh-sticky-header--visible {
      display: grid;
      grid-auto-flow: column;
      pointer-events: auto;
    }

    /* Disable the gauge arc animation for the sticky header, so toggling display: none
       does not play the animation. */
    .lh-sticky-header .lh-gauge-arc {
      animation: none;
    }

    .lh-sticky-header .lh-gauge__label {
      display: none;
    }

    .lh-highlighter {
      width: var(--gauge-wrapper-width);
      height: 1px;
      background-color: var(--highlighter-background-color);
      /* Position at bottom of first gauge in sticky header. */
      position: absolute;
      grid-column: 1;
      bottom: -1px;
    }

    .lh-gauge__wrapper:first-of-type {
      contain: none;
    }
  </style>
  <div class="lh-scores-wrapper">
    <div class="lh-scores-container">
      <div class="pyro">
        <div class="before"></div>
        <div class="after"></div>
      </div>
    </div>
  </div>
</template>

<!-- Lighthouse topbar -->
<template id="tmpl-lh-topbar">
  <style>
    .lh-topbar {
      position: sticky;
      top: 0;
      left: 0;
      right: 0;
      z-index: 1000;
      display: flex;
      align-items: center;
      height: var(--topbar-height);
      background-color: var(--topbar-background-color);
      padding: var(--topbar-padding);
    }

    .lh-topbar__logo {
      width: var(--topbar-logo-size);
      height: var(--topbar-logo-size);
      user-select: none;
      flex: none;
    }
    .lh-topbar__logo .shape {
      fill: var(--report-text-color);
    }

    .lh-topbar__url {
      margin: var(--topbar-padding);
      text-decoration: none;
      color: var(--report-text-color);
      text-overflow: ellipsis;
      overflow: hidden;
      white-space: nowrap;
    }

    .lh-tools {
      margin-left: auto;
      will-change: transform;
    }
    .lh-tools__button {
      width: var(--tools-icon-size);
      height: var(--tools-icon-size);
      cursor: pointer;
      margin-right: 5px;
      /* This is actually a button element, but we want to style it like a transparent div. */
      display: flex;
      background: none;
      color: inherit;
      border: none;
      padding: 0;
      font: inherit;
      outline: inherit;
    }
    .lh-tools__button svg {
      fill: var(--tools-icon-color);
    }
    .dark .lh-tools__button svg {
      filter: invert(1);
    }
    .lh-tools__button.active + .lh-tools__dropdown {
      opacity: 1;
      clip: rect(-1px, 187px, 242px, -3px);
      visibility: visible;
    }
    .lh-tools__dropdown {
      position: absolute;
      background-color: var(--report-background-color);
      border: 1px solid var(--report-border-color);
      border-radius: 3px;
      padding: calc(var(--default-padding) / 2) 0;
      cursor: pointer;
      top: 36px;
      right: 0;
      box-shadow: 1px 1px 3px #ccc;
      min-width: 125px;
      clip: rect(0, 164px, 0, 0);
      visibility: hidden;
      opacity: 0;
      transition: all 200ms cubic-bezier(0,0,0.2,1);
    }
    .lh-tools__dropdown a {
      display: block;
      color: currentColor;
      text-decoration: none;
      white-space: nowrap;
      padding: 0 12px;
      line-height: 2;
    }
    .lh-tools__dropdown a:hover,
    .lh-tools__dropdown a:focus {
      background-color: var(--color-gray-200);
      outline: none;
    }
    .lh-tools__dropdown .report-icon {
      cursor: pointer;
      background-repeat: no-repeat;
      background-position: 8px 50%;
      background-size: 18px;
      background-color: transparent;
      text-indent: 18px;
    }
    .dark .report-icon {
      color: var(--color-gray-900);
      filter: invert(1);
    }
    .dark .lh-tools__dropdown a:hover,
    .dark .lh-tools__dropdown a:focus {
      background-color: #BDBDBD;
    }
    /* copy icon needs slight adjustments to look great */
    .lh-tools__dropdown .report-icon--copy {
      background-size: 16px;
      background-position: 9px 50%;
    }
    /* save-as-gist option hidden in report */
    .lh-tools__dropdown .lh-tools--gist {
      display: none;
    }

    @media screen and (max-width: 964px) {
      .lh-tools__dropdown {
        right: 0;
        left: initial;
      }
    }
    @media print {
      .lh-topbar {
        position: static;
        margin-left: 0;
      }
    }
  </style>

  <div class="lh-topbar">
    <!-- Lighthouse logo.  -->
    <svg class="lh-topbar__logo" viewBox="0 0 24 24">
      <defs>
        <linearGradient x1="57.456%" y1="13.086%" x2="18.259%" y2="72.322%" id="lh-topbar__logo--a">
          <stop stop-color="#262626" stop-opacity=".1" offset="0%"/>
          <stop stop-color="#262626" stop-opacity="0" offset="100%"/>
        </linearGradient>
        <linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="lh-topbar__logo--b">
          <stop stop-color="#262626" stop-opacity=".1" offset="0%"/>
          <stop stop-color="#262626" stop-opacity="0" offset="100%"/>
        </linearGradient>
        <linearGradient x1="58.764%" y1="65.756%" x2="36.939%" y2="50.14%" id="lh-topbar__logo--c">
          <stop stop-color="#262626" stop-opacity=".1" offset="0%"/>
          <stop stop-color="#262626" stop-opacity="0" offset="100%"/>
        </linearGradient>
        <linearGradient x1="41.635%" y1="20.358%" x2="72.863%" y2="85.424%" id="lh-topbar__logo--d">
          <stop stop-color="#FFF" stop-opacity=".1" offset="0%"/>
          <stop stop-color="#FFF" stop-opacity="0" offset="100%"/>
        </linearGradient>
      </defs>
      <g fill="none" fill-rule="evenodd">
        <path d="M12 3l4.125 2.625v3.75H18v2.25h-1.688l1.5 9.375H6.188l1.5-9.375H6v-2.25h1.875V5.648L12 3zm2.201 9.938L9.54 14.633 9 18.028l5.625-2.062-.424-3.028zM12.005 5.67l-1.88 1.207v2.498h3.75V6.86l-1.87-1.19z" fill="#F44B21"/>
        <path fill="#FFF" d="M14.201 12.938L9.54 14.633 9 18.028l5.625-2.062z"/>
        <path d="M6 18c-2.042 0-3.95-.01-5.813 0l1.5-9.375h4.326L6 18z" fill="url(#lh-topbar__logo--a)" fill-rule="nonzero" transform="translate(6 3)"/>
        <path fill="#FFF176" fill-rule="nonzero" d="M13.875 9.375v-2.56l-1.87-1.19-1.88 1.207v2.543z"/>
        <path fill="url(#lh-topbar__logo--b)" fill-rule="nonzero" d="M0 6.375h6v2.25H0z" transform="translate(6 3)"/>
        <path fill="url(#lh-topbar__logo--c)" fill-rule="nonzero" d="M6 6.375H1.875v-3.75L6 0z" transform="translate(6 3)"/>
        <path fill="url(#lh-topbar__logo--d)" fill-rule="nonzero" d="M6 0l4.125 2.625v3.75H12v2.25h-1.688l1.5 9.375H.188l1.5-9.375H0v-2.25h1.875V2.648z" transform="translate(6 3)"/>
      </g>
    </svg>

    <a href="" class="lh-topbar__url" target="_blank" rel="noopener"></a>

    <div class="lh-tools">
      <button id="lh-tools-button" class="report-icon report-icon--share lh-tools__button" title="Tools menu" aria-label="Toggle report tools menu" aria-haspopup="menu" aria-expanded="false" aria-controls="lh-tools-dropdown">
        <svg width="100%" height="100%" viewBox="0 0 24 24">
            <path d="M0 0h24v24H0z" fill="none"/>
            <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
        </svg>
      </button>
      <div id="lh-tools-dropdown" role="menu" class="lh-tools__dropdown" aria-labelledby="lh-tools-button">
         <!-- TODO(i18n): localize tools dropdown -->
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--print" data-action="print-summary">Print Summary</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--print" data-action="print-expanded">Print Expanded</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--copy" data-action="copy">Copy JSON</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--download" data-action="save-html">Save as HTML</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--download" data-action="save-json">Save as JSON</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--open lh-tools--viewer" data-action="open-viewer">Open in Viewer</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--open lh-tools--gist" data-action="save-gist">Save as Gist</a>
        <a role="menuitem" tabindex="-1" href="#" class="report-icon report-icon--dark" data-action="toggle-dark">Toggle Dark Theme</a>
      </div>
    </div>
  </div>
</template>

<!-- Lighthouse header -->
<template id="tmpl-lh-heading">
  <style>
    /* CSS Fireworks. Originally by Eddie Lin
       https://codepen.io/paulirish/pen/yEVMbP
    */
    .pyro {
      display: none;
      z-index: 1;
      pointer-events: none;
    }
    .score100 .pyro {
      display: block;
    }
    .score100 .lh-lighthouse stop:first-child {
      stop-color: hsla(200, 12%, 95%, 0);
    }
    .score100 .lh-lighthouse stop:last-child {
      stop-color: hsla(65, 81%, 76%, 1);
    }

    .pyro > .before, .pyro > .after {
      position: absolute;
      width: 5px;
      height: 5px;
      border-radius: 2.5px;
      box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;
      animation: 1s bang ease-out infinite backwards,  1s gravity ease-in infinite backwards,  5s position linear infinite backwards;
      animation-delay: 1s, 1s, 1s;
    }

    .pyro > .after {
      animation-delay: 2.25s, 2.25s, 2.25s;
      animation-duration: 1.25s, 1.25s, 6.25s;
    }
    .fireworks-paused .pyro > div {
      animation-play-state: paused;
    }

    @keyframes bang {
      to {
        box-shadow: -70px -115.67px #47ebbc, -28px -99.67px #eb47a4, 58px -31.67px #7eeb47, 13px -141.67px #eb47c5, -19px 6.33px #7347eb, -2px -74.67px #ebd247, 24px -151.67px #eb47e0, 57px -138.67px #b4eb47, -51px -104.67px #479eeb, 62px 8.33px #ebcf47, -93px 0.33px #d547eb, -16px -118.67px #47bfeb, 53px -84.67px #47eb83, 66px -57.67px #eb47bf, -93px -65.67px #91eb47, 30px -13.67px #86eb47, -2px -59.67px #83eb47, -44px 1.33px #eb47eb, 61px -58.67px #47eb73, 5px -22.67px #47e8eb, -66px -28.67px #ebe247, 42px -123.67px #eb5547, -75px 26.33px #7beb47, 15px -52.67px #a147eb, 36px -51.67px #eb8347, -38px -12.67px #eb5547, -46px -59.67px #47eb81, 78px -114.67px #eb47ba, 15px -156.67px #eb47bf, -36px 1.33px #eb4783, -72px -86.67px #eba147, 31px -46.67px #ebe247, -68px 29.33px #47e2eb, -55px 19.33px #ebe047, -56px 27.33px #4776eb, -13px -91.67px #eb5547, -47px -138.67px #47ebc7, -18px -96.67px #eb47ac, 11px -88.67px #4783eb, -67px -28.67px #47baeb, 53px 10.33px #ba47eb, 11px 19.33px #5247eb, -5px -11.67px #eb4791, -68px -4.67px #47eba7, 95px -37.67px #eb478b, -67px -162.67px #eb5d47, -54px -120.67px #eb6847, 49px -12.67px #ebe047, 88px 8.33px #47ebda, 97px 33.33px #eb8147, 6px -71.67px #ebbc47;
      }
    }
    @keyframes gravity {
      to {
        transform: translateY(80px);
        opacity: 0;
      }
    }
    @keyframes position {
      0%, 19.9% {
        margin-top: 4%;
        margin-left: 47%;
      }
      20%, 39.9% {
        margin-top: 7%;
        margin-left: 30%;
      }
      40%, 59.9% {
        margin-top: 6%;
        margin-left: 70%;
      }
      60%, 79.9% {
        margin-top: 3%;
        margin-left: 20%;
      }
      80%, 99.9% {
        margin-top: 3%;
        margin-left: 80%;
      }
    }
  </style>

  <div class="lh-header-container">
    <div class="lh-scores-wrapper-placeholder"></div>
  </div>
</template>


<!-- Lighthouse footer -->
<template id="tmpl-lh-footer">
  <style>
    .lh-footer {
      padding: var(--footer-padding-vertical) calc(var(--default-padding) * 2);
      max-width: var(--report-width);
      margin: 0 auto;
    }
    .lh-footer .lh-generated {
      text-align: center;
    }
    .lh-env__title {
      font-size: var(--env-item-font-size-big);
      line-height: var(--env-item-line-height-big);
      text-align: center;
      padding: var(--score-container-padding);
    }
    .lh-env {
      padding: var(--default-padding) 0;
    }
    .lh-env__items {
      padding-left: 16px;
      margin: 0 0 var(--audits-margin-bottom);
      padding: 0;
    }
    .lh-env__items .lh-env__item:nth-child(2n) {
      background-color: var(--env-item-background-color);
    }
    .lh-env__item {
      display: flex;
      padding: var(--env-item-padding);
      position: relative;
    }
    span.lh-env__name {
      font-weight: bold;
      min-width: var(--env-name-min-width);
      flex: 0.5;
      padding: 0 8px;
    }
    span.lh-env__description {
      text-align: left;
      flex: 1;
    }
  </style>
  <footer class="lh-footer">
    <!-- TODO(i18n): localize runtime settings -->
    <div class="lh-env">
      <div class="lh-env__title">Runtime Settings</div>
      <ul class="lh-env__items">
        <template id="tmpl-lh-env__items">
          <li class="lh-env__item">
            <span class="lh-env__name"></span>
            <span class="lh-env__description"></span>
          </li>
        </template>
      </ul>
    </div>

    <div class="lh-generated">
      Generated by <b>Lighthouse</b> <span class="lh-footer__version"></span> |
      <a href="https://github.com/GoogleChrome/Lighthouse/issues" target="_blank" rel="noopener">File an issue</a>
    </div>
  </footer>
</template>

<!-- Lighthouse score gauge -->
<template id="tmpl-lh-gauge">
  <a href="#" class="lh-gauge__wrapper">
    <!-- Wrapper exists for the ::before plugin icon. Cannot create pseudo-elements on svgs. -->
    <div class="lh-gauge__svg-wrapper">
      <svg viewBox="0 0 120 120" class="lh-gauge">
        <circle class="lh-gauge-base" r="56" cx="60" cy="60"></circle>
        <circle class="lh-gauge-arc" transform="rotate(-90 60 60)" r="56" cx="60" cy="60"></circle>
      </svg>
    </div>
    <div class="lh-gauge__percentage"></div>
    <!-- TODO: should likely be an h2  -->
    <div class="lh-gauge__label"></div>
  </a>
</template>


<!-- Lighthouse PWA badge gauge -->
<template id="tmpl-lh-gauge--pwa">
  <style>
    .lh-gauge--pwa .lh-gauge--pwa__component {
      display: none;
    }
    .lh-gauge--pwa__wrapper:not(.lh-badged--all) .lh-gauge--pwa__logo > path {
      /* Gray logo unless everything is passing. */
      fill: #B0B0B0;
    }

    .lh-gauge--pwa__disc {
      fill: var(--color-gray-200);
    }

    .lh-gauge--pwa__logo--primary-color {
      fill: #304FFE;
    }

    .lh-gauge--pwa__logo--secondary-color {
      fill: #3D3D3D;
    }
    .dark .lh-gauge--pwa__logo--secondary-color {
      fill: #D8B6B6;
    }

    /* No passing groups. */
    .lh-gauge--pwa__wrapper:not([class*='lh-badged--']) .lh-gauge--pwa__na-line {
      display: inline;
    }
    /* Just optimized. Same n/a line as no passing groups. */
    .lh-gauge--pwa__wrapper.lh-badged--pwa-optimized:not(.lh-badged--pwa-installable):not(.lh-badged--pwa-fast-reliable) .lh-gauge--pwa__na-line {
      display: inline;
    }

    /* Just fast and reliable. */
    .lh-gauge--pwa__wrapper.lh-badged--pwa-fast-reliable:not(.lh-badged--pwa-installable) .lh-gauge--pwa__fast-reliable-badge {
      display: inline;
    }

    /* Just installable. */
    .lh-gauge--pwa__wrapper.lh-badged--pwa-installable:not(.lh-badged--pwa-fast-reliable) .lh-gauge--pwa__installable-badge {
      display: inline;
    }

    /* Fast and reliable and installable. */
    .lh-gauge--pwa__wrapper.lh-badged--pwa-fast-reliable.lh-badged--pwa-installable .lh-gauge--pwa__fast-reliable-installable-badges {
      display: inline;
    }

    /* All passing groups. */
    .lh-gauge--pwa__wrapper.lh-badged--all .lh-gauge--pwa__check-circle {
      display: inline;
    }
  </style>

  <a href="#" class="lh-gauge__wrapper lh-gauge--pwa__wrapper">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" class="lh-gauge lh-gauge--pwa">
      <defs>
        <linearGradient id="lh-gauge--pwa__check-circle__gradient" x1="50%" y1="0%" x2="50%" y2="100%">
          <stop stop-color="#00C852" offset="0%"></stop>
          <stop stop-color="#009688" offset="100%"></stop>
        </linearGradient>
        <linearGradient id="lh-gauge--pwa__installable__shadow-gradient" x1="76.056%" x2="24.111%" y1="82.995%" y2="24.735%">
          <stop stop-color="#A5D6A7" offset="0%"></stop>
          <stop stop-color="#80CBC4" offset="100%"></stop>
        </linearGradient>
        <linearGradient id="lh-gauge--pwa__fast-reliable__shadow-gradient" x1="76.056%" y1="82.995%" x2="25.678%" y2="26.493%">
          <stop stop-color="#64B5F6" offset="0%"></stop>
          <stop stop-color="#2979FF" offset="100%"></stop>
        </linearGradient>

        <g id="lh-gauge--pwa__fast-reliable-badge">
          <circle fill="#FFFFFF" cx="10" cy="10" r="10"></circle>
          <path fill="#304FFE" d="M10 3.58l5.25 2.34v3.5c0 3.23-2.24 6.26-5.25 7-3.01-.74-5.25-3.77-5.25-7v-3.5L10 3.58zm-.47 10.74l2.76-4.83.03-.07c.04-.08 0-.24-.22-.24h-1.64l.47-3.26h-.47l-2.7 4.77c-.02.01.05-.1-.04.05-.09.16-.1.31.18.31h1.63l-.47 3.27h.47z"/>
        </g>
        <g id="lh-gauge--pwa__installable-badge">
          <circle fill="#FFFFFF" cx="10" cy="10" r="10"></circle>
          <path fill="#009688" d="M10 4.167A5.835 5.835 0 0 0 4.167 10 5.835 5.835 0 0 0 10 15.833 5.835 5.835 0 0 0 15.833 10 5.835 5.835 0 0 0 10 4.167zm2.917 6.416h-2.334v2.334H9.417v-2.334H7.083V9.417h2.334V7.083h1.166v2.334h2.334v1.166z"/>
        </g>
      </defs>

      <g stroke="none" fill-rule="nonzero">
        <!-- Background and PWA logo (color by default) -->
        <circle class="lh-gauge--pwa__disc" cx="30" cy="30" r="30"></circle>
        <g class="lh-gauge--pwa__logo">
          <path class="lh-gauge--pwa__logo--secondary-color" d="M35.66 19.39l.7-1.75h2L37.4 15 38.6 12l3.4 9h-2.51l-.58-1.61z"/>
          <path class="lh-gauge--pwa__logo--primary-color" d="M33.52 21l3.65-9h-2.42l-2.5 5.82L30.5 12h-1.86l-1.9 5.82-1.35-2.65-1.21 3.72L25.4 21h2.38l1.72-5.2 1.64 5.2z"/>
          <path class="lh-gauge--pwa__logo--secondary-color" fill-rule="nonzero" d="M20.3 17.91h1.48c.45 0 .85-.05 1.2-.15l.39-1.18 1.07-3.3a2.64 2.64 0 0 0-.28-.37c-.55-.6-1.36-.91-2.42-.91H18v9h2.3V17.9zm1.96-3.84c.22.22.33.5.33.87 0 .36-.1.65-.29.87-.2.23-.59.35-1.15.35h-.86v-2.41h.87c.52 0 .89.1 1.1.32z"/>
        </g>

        <!-- No badges. -->
        <rect class="lh-gauge--pwa__component lh-gauge--pwa__na-line" fill="#FFFFFF" x="20" y="32" width="20" height="4" rx="2"></rect>

        <!-- Just fast and reliable. -->
        <g class="lh-gauge--pwa__component lh-gauge--pwa__fast-reliable-badge" transform="translate(20, 29)">
          <path fill="url(#lh-gauge--pwa__fast-reliable__shadow-gradient)" d="M33.63 19.49A30 30 0 0 1 16.2 30.36L3 17.14 17.14 3l16.49 16.49z"/>
          <use href="#lh-gauge--pwa__fast-reliable-badge" />
        </g>

        <!-- Just installable. -->
        <g class="lh-gauge--pwa__component lh-gauge--pwa__installable-badge" transform="translate(20, 29)">
          <path fill="url(#lh-gauge--pwa__installable__shadow-gradient)" d="M33.629 19.487c-4.272 5.453-10.391 9.39-17.415 10.869L3 17.142 17.142 3 33.63 19.487z"/>
          <use href="#lh-gauge--pwa__installable-badge" />
        </g>

        <!-- Fast and reliable and installable. -->
        <g class="lh-gauge--pwa__component lh-gauge--pwa__fast-reliable-installable-badges">
          <g transform="translate(8, 29)"> <!-- fast and reliable -->
            <path fill="url(#lh-gauge--pwa__fast-reliable__shadow-gradient)" d="M16.321 30.463L3 17.143 17.142 3l22.365 22.365A29.864 29.864 0 0 1 22 31c-1.942 0-3.84-.184-5.679-.537z"/>
            <use href="#lh-gauge--pwa__fast-reliable-badge" />
          </g>
          <g transform="translate(32, 29)"> <!-- installable -->
            <path fill="url(#lh-gauge--pwa__installable__shadow-gradient)" d="M25.982 11.84a30.107 30.107 0 0 1-13.08 15.203L3 17.143 17.142 3l8.84 8.84z"/>
            <use href="#lh-gauge--pwa__installable-badge" />
          </g>
        </g>

        <!-- Full PWA. -->
        <g class="lh-gauge--pwa__component lh-gauge--pwa__check-circle" transform="translate(18, 28)">
          <circle fill="#FFFFFF" cx="12" cy="12" r="12"></circle>
          <path fill="url(#lh-gauge--pwa__check-circle__gradient)" d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path>
        </g>
      </g>
    </svg>

    <div class="lh-gauge__label"></div>
  </a>
</template>

<!-- Lighthouse crtiical request chains component -->
<template id="tmpl-lh-crc">
  <div class="lh-crc-container">
    <style>
      .lh-crc .tree-marker {
        width: 12px;
        height: 26px;
        display: block;
        float: left;
        background-position: top left;
      }
      .lh-crc .horiz-down {
        background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><g fill="%23D8D8D8" fill-rule="evenodd"><path d="M16 12v2H-2v-2z"/><path d="M9 12v14H7V12z"/></g></svg>');
      }
      .lh-crc .right {
        background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M16 12v2H0v-2z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
      }
      .lh-crc .up-right {
        background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v14H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
      }
      .lh-crc .vert-right {
        background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v27H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
      }
      .lh-crc .vert {
        background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v26H7z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
      }
      .lh-crc .crc-tree {
        font-size: 14px;
        width: 100%;
        overflow-x: auto;
      }
      .lh-crc .crc-node {
        height: 26px;
        line-height: 26px;
        white-space: nowrap;
      }
      .lh-crc .crc-node__tree-value {
        margin-left: 10px;
      }
      .lh-crc .crc-node__tree-value div {
        display: inline;
      }
      .lh-crc .crc-node__chain-duration {
        font-weight: 700;
      }
      .lh-crc .crc-initial-nav {
        color: #595959;
        font-style: italic;
      }
      .lh-crc__summary-value {
        margin-bottom: 10px;
      }
    </style>
    <div>
      <div class="lh-crc__summary-value">
        <span class="lh-crc__longest_duration_label"></span> <b class="lh-crc__longest_duration"></b>
      </div>
    </div>
    <div class="lh-crc">
      <div class="crc-initial-nav"></div>
      <!-- stamp for each chain -->
      <template id="tmpl-lh-crc__chains">
        <div class="crc-node">
          <span class="crc-node__tree-marker">

          </span>
          <span class="crc-node__tree-value">

          </span>
        </div>
      </template>
    </div>
  </div>
</template>

<template id="tmpl-lh-3p-filter">
  <style>
    .lh-3p-filter {
      background-color: var(--table-higlight-background-color);
      color: var(--color-gray-600);
      float: right;
      padding: 6px;
    }
    .lh-3p-filter-label, .lh-3p-filter-input {
      vertical-align: middle;
      user-select: none;
    }
    .lh-3p-filter-input:disabled + .lh-3p-ui-string {
      text-decoration: line-through;
    }
  </style>
  <div class="lh-3p-filter">
    <label class="lh-3p-filter-label">
      <input type="checkbox" class="lh-3p-filter-input" checked />
      <span class="lh-3p-ui-string">Show 3rd party resources</span> (<span class="lh-3p-filter-count"></span>)
    </label>
  </div>
</template>

<!-- Lighthouse snippet component -->
<template id="tmpl-lh-snippet">
    <div class="lh-snippet">
      <style>
          :root {
            --snippet-highlight-light: #fbf1f2;
            --snippet-highlight-dark: #ffd6d8;
          }

         .lh-snippet__header {
          position: relative;
          overflow: hidden;
          padding: 10px;
          border-bottom: none;
          color: var(--snippet-color);
          background-color: var(--snippet-background-color);
          border: 1px solid var(--report-border-color-secondary);
        }
        .lh-snippet__title {
          font-weight: bold;
          float: left;
        }
        .lh-snippet__node {
          float: left;
          margin-left: 4px;
        }
        .lh-snippet__toggle-expand {
          padding: 1px 7px;
          margin-top: -1px;
          margin-right: -7px;
          float: right;
          background: transparent;
          border: none;
          cursor: pointer;
          font-size: 14px;
          color: #0c50c7;
        }

        .lh-snippet__snippet {
          overflow: auto;
          border: 1px solid var(--report-border-color-secondary);
        }
        /* Container needed so that all children grow to the width of the scroll container */
        .lh-snippet__snippet-inner {
          display: inline-block;
          min-width: 100%;
        }

        .lh-snippet:not(.lh-snippet--expanded) .lh-snippet__show-if-expanded {
          display: none;
        }
        .lh-snippet.lh-snippet--expanded .lh-snippet__show-if-collapsed {
          display: none;
        }

        .lh-snippet__line {
          background: white;
          white-space: pre;
          display: flex;
        }
        .lh-snippet__line:not(.lh-snippet__line--message):first-child {
          padding-top: 4px;
        }
        .lh-snippet__line:not(.lh-snippet__line--message):last-child {
          padding-bottom: 4px;
        }
        .lh-snippet__line--content-highlighted {
          background: var(--snippet-highlight-dark);
        }
        .lh-snippet__line--message {
          background: var(--snippet-highlight-light);
        }
        .lh-snippet__line--message .lh-snippet__line-number {
          padding-top: 10px;
          padding-bottom: 10px;
        }
        .lh-snippet__line--message code {
          padding: 10px;
          padding-left: 5px;
          color: var(--color-fail);
          font-family: var(--report-font-family);
        }
        .lh-snippet__line--message code {
          white-space: normal;
        }
        .lh-snippet__line-icon {
          padding-top: 10px;
          display: none;
        }
        .lh-snippet__line--message .lh-snippet__line-icon {
          display: block;
        }
        .lh-snippet__line-icon:before {
          content: "";
          display: inline-block;
          vertical-align: middle;
          margin-right: 4px;
          width: var(--score-icon-size);
          height: var(--score-icon-size);
          background-image: var(--fail-icon-url);
        }
        .lh-snippet__line-number {
          flex-shrink: 0;
          width: 40px;
          text-align: right;
          font-family: monospace;
          padding-right: 5px;
          margin-right: 5px;
          color: var(--color-gray-600);
          user-select: none;
        }
      </style>
      <template id="tmpl-lh-snippet__header">
        <div class="lh-snippet__header">
          <div class="lh-snippet__title"></div>
          <div class="lh-snippet__node"></div>
          <button class="lh-snippet__toggle-expand">
            <span class="lh-snippet__btn-label-collapse lh-snippet__show-if-expanded"></span>
            <span class="lh-snippet__btn-label-expand lh-snippet__show-if-collapsed"></span>
          </button>
        </div>
      </template>
      <template id="tmpl-lh-snippet__content">
        <div class="lh-snippet__snippet">
          <div class="lh-snippet__snippet-inner"></div>
        </div>
      </template>
      <template id="tmpl-lh-snippet__line">
          <div class="lh-snippet__line">
            <div class="lh-snippet__line-number"></div>
            <div class="lh-snippet__line-icon"></div>
            <code></code>
          </div>
        </template>
    </div>
  </template>

</div>

  <main><!-- report populated here --></main>

  <div id="lh-log"></div>

  <script>/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* globals self, URL */

const ELLIPSIS = '\u2026';
const NBSP = '\xa0';
const PASS_THRESHOLD = 0.9;
const SCREENSHOT_PREFIX = 'data:image/jpeg;base64,';

const RATINGS = {
  PASS: {label: 'pass', minScore: PASS_THRESHOLD},
  AVERAGE: {label: 'average', minScore: 0.5},
  FAIL: {label: 'fail'},
  ERROR: {label: 'error'},
};

// 25 most used tld plus one domains (aka public suffixes) from http archive.
// @see https://github.com/GoogleChrome/lighthouse/pull/5065#discussion_r191926212
// The canonical list is https://publicsuffix.org/learn/ but we're only using subset to conserve bytes
const listOfTlds = [
  'com', 'co', 'gov', 'edu', 'ac', 'org', 'go', 'gob', 'or', 'net', 'in', 'ne', 'nic', 'gouv',
  'web', 'spb', 'blog', 'jus', 'kiev', 'mil', 'wi', 'qc', 'ca', 'bel', 'on',
];

class Util {
  static get PASS_THRESHOLD() {
    return PASS_THRESHOLD;
  }

  static get MS_DISPLAY_VALUE() {
    return `%10d${NBSP}ms`;
  }

  /**
   * Returns a new LHR that's reshaped for slightly better ergonomics within the report rendereer.
   * Also, sets up the localized UI strings used within renderer and makes changes to old LHRs to be
   * compatible with current renderer.
   * The LHR passed in is not mutated.
   * TODO(team): we all agree the LHR shape change is technical debt we should fix
   * @param {LH.Result} result
   * @return {LH.ReportResult}
   */
  static prepareReportResult(result) {
    // If any mutations happen to the report within the renderers, we want the original object untouched
    const clone = /** @type {LH.ReportResult} */ (JSON.parse(JSON.stringify(result)));

    // If LHR is older (≤3.0.3), it has no locale setting. Set default.
    if (!clone.configSettings.locale) {
      clone.configSettings.locale = 'en';
    }

    for (const audit of Object.values(clone.audits)) {
      // Turn 'not-applicable' (LHR <4.0) and 'not_applicable' (older proto versions)
      // into 'notApplicable' (LHR ≥4.0).
      // @ts-ignore tsc rightly flags that these values shouldn't occur.
      // eslint-disable-next-line max-len
      if (audit.scoreDisplayMode === 'not_applicable' || audit.scoreDisplayMode === 'not-applicable') {
        audit.scoreDisplayMode = 'notApplicable';
      }

      if (audit.details) {
        // Turn `auditDetails.type` of undefined (LHR <4.2) and 'diagnostic' (LHR <5.0)
        // into 'debugdata' (LHR ≥5.0).
        // @ts-ignore tsc rightly flags that these values shouldn't occur.
        if (audit.details.type === undefined || audit.details.type === 'diagnostic') {
          audit.details.type = 'debugdata';
        }

        // Add the jpg data URL prefix to filmstrip screenshots without them (LHR <5.0).
        if (audit.details.type === 'filmstrip') {
          for (const screenshot of audit.details.items) {
            if (!screenshot.data.startsWith(SCREENSHOT_PREFIX)) {
              screenshot.data = SCREENSHOT_PREFIX + screenshot.data;
            }
          }
        }
      }
    }

    // Set locale for number/date formatting and grab localized renderer strings from the LHR.
    Util.setNumberDateLocale(clone.configSettings.locale);
    if (clone.i18n && clone.i18n.rendererFormattedStrings) {
      Util.updateAllUIStrings(clone.i18n.rendererFormattedStrings);
    }

    // For convenience, smoosh all AuditResults into their auditRef (which has just weight & group)
    if (typeof clone.categories !== 'object') throw new Error('No categories provided.');
    for (const category of Object.values(clone.categories)) {
      category.auditRefs.forEach(auditRef => {
        const result = clone.audits[auditRef.id];
        auditRef.result = result;

        // attach the stackpacks to the auditRef object
        if (clone.stackPacks) {
          clone.stackPacks.forEach(pack => {
            if (pack.descriptions[auditRef.id]) {
              auditRef.stackPacks = auditRef.stackPacks || [];
              auditRef.stackPacks.push({
                title: pack.title,
                iconDataURL: pack.iconDataURL,
                description: pack.descriptions[auditRef.id],
              });
            }
          });
        }
      });
    }

    return clone;
  }


  /**
   * @param {LH.I18NRendererStrings} rendererFormattedStrings
   */
  static updateAllUIStrings(rendererFormattedStrings) {
    // TODO(i18n): don't mutate these here but on the LHR and pass that around everywhere
    for (const [key, value] of Object.entries(rendererFormattedStrings)) {
      Util.UIStrings[key] = value;
    }
  }

  /**
   * Used to determine if the "passed" for the purposes of showing up in the "failed" or "passed"
   * sections of the report.
   *
   * @param {{score: (number|null), scoreDisplayMode: string}} audit
   * @return {boolean}
   */
  static showAsPassed(audit) {
    switch (audit.scoreDisplayMode) {
      case 'manual':
      case 'notApplicable':
        return true;
      case 'error':
      case 'informative':
        return false;
      case 'numeric':
      case 'binary':
      default:
        return Number(audit.score) >= RATINGS.PASS.minScore;
    }
  }

  /**
   * Convert a score to a rating label.
   * @param {number|null} score
   * @param {string=} scoreDisplayMode
   * @return {string}
   */
  static calculateRating(score, scoreDisplayMode) {
    // Handle edge cases first, manual and not applicable receive 'pass', errored audits receive 'error'
    if (scoreDisplayMode === 'manual' || scoreDisplayMode === 'notApplicable') {
      return RATINGS.PASS.label;
    } else if (scoreDisplayMode === 'error') {
      return RATINGS.ERROR.label;
    } else if (score === null) {
      return RATINGS.FAIL.label;
    }

    // At this point, we're rating a standard binary/numeric audit
    let rating = RATINGS.FAIL.label;
    if (score >= RATINGS.PASS.minScore) {
      rating = RATINGS.PASS.label;
    } else if (score >= RATINGS.AVERAGE.minScore) {
      rating = RATINGS.AVERAGE.label;
    }
    return rating;
  }

  /**
   * Format number.
   * @param {number} number
   * @param {number=} granularity Number of decimal places to include. Defaults to 0.1.
   * @return {string}
   */
  static formatNumber(number, granularity = 0.1) {
    const coarseValue = Math.round(number / granularity) * granularity;
    return Util.numberFormatter.format(coarseValue);
  }

  /**
   * @param {number} size
   * @param {number=} granularity Controls how coarse the displayed value is, defaults to .01
   * @return {string}
   */
  static formatBytesToKB(size, granularity = 0.1) {
    const kbs = Util.numberFormatter.format(Math.round(size / 1024 / granularity) * granularity);
    return `${kbs}${NBSP}KB`;
  }

  /**
   * @param {number} ms
   * @param {number=} granularity Controls how coarse the displayed value is, defaults to 10
   * @return {string}
   */
  static formatMilliseconds(ms, granularity = 10) {
    const coarseTime = Math.round(ms / granularity) * granularity;
    return `${Util.numberFormatter.format(coarseTime)}${NBSP}ms`;
  }

  /**
   * @param {number} ms
   * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
   * @return {string}
   */
  static formatSeconds(ms, granularity = 0.1) {
    const coarseTime = Math.round(ms / 1000 / granularity) * granularity;
    return `${Util.numberFormatter.format(coarseTime)}${NBSP}s`;
  }

  /**
   * Format time.
   * @param {string} date
   * @return {string}
   */
  static formatDateTime(date) {
    /** @type {Intl.DateTimeFormatOptions} */
    const options = {
      month: 'short', day: 'numeric', year: 'numeric',
      hour: 'numeric', minute: 'numeric', timeZoneName: 'short',
    };
    let formatter = new Intl.DateTimeFormat(Util.numberDateLocale, options);

    // Force UTC if runtime timezone could not be detected.
    // See https://github.com/GoogleChrome/lighthouse/issues/1056
    const tz = formatter.resolvedOptions().timeZone;
    if (!tz || tz.toLowerCase() === 'etc/unknown') {
      options.timeZone = 'UTC';
      formatter = new Intl.DateTimeFormat(Util.numberDateLocale, options);
    }
    return formatter.format(new Date(date));
  }
  /**
   * Converts a time in milliseconds into a duration string, i.e. `1d 2h 13m 52s`
   * @param {number} timeInMilliseconds
   * @return {string}
   */
  static formatDuration(timeInMilliseconds) {
    let timeInSeconds = timeInMilliseconds / 1000;
    if (Math.round(timeInSeconds) === 0) {
      return 'None';
    }

    /** @type {Array<string>} */
    const parts = [];
    const unitLabels = /** @type {Object<string, number>} */ ({
      d: 60 * 60 * 24,
      h: 60 * 60,
      m: 60,
      s: 1,
    });

    Object.keys(unitLabels).forEach(label => {
      const unit = unitLabels[label];
      const numberOfUnits = Math.floor(timeInSeconds / unit);
      if (numberOfUnits > 0) {
        timeInSeconds -= numberOfUnits * unit;
        parts.push(`${numberOfUnits}\xa0${label}`);
      }
    });

    return parts.join(' ');
  }

  /**
   * Split a string by markdown code spans (enclosed in `backticks`), splitting
   * into segments that were enclosed in backticks (marked as `isCode === true`)
   * and those that outside the backticks (`isCode === false`).
   * @param {string} text
   * @return {Array<{isCode: true, text: string}|{isCode: false, text: string}>}
   */
  static splitMarkdownCodeSpans(text) {
    /** @type {Array<{isCode: true, text: string}|{isCode: false, text: string}>} */
    const segments = [];

    // Split on backticked code spans.
    const parts = text.split(/`(.*?)`/g);
    for (let i = 0; i < parts.length; i ++) {
      const text = parts[i];

      // Empty strings are an artifact of splitting, not meaningful.
      if (!text) continue;

      // Alternates between plain text and code segments.
      const isCode = i % 2 !== 0;
      segments.push({
        isCode,
        text,
      });
    }

    return segments;
  }

  /**
   * Split a string on markdown links (e.g. [some link](https://...)) into
   * segments of plain text that weren't part of a link (marked as
   * `isLink === false`), and segments with text content and a URL that did make
   * up a link (marked as `isLink === true`).
   * @param {string} text
   * @return {Array<{isLink: true, text: string, linkHref: string}|{isLink: false, text: string}>}
   */
  static splitMarkdownLink(text) {
    /** @type {Array<{isLink: true, text: string, linkHref: string}|{isLink: false, text: string}>} */
    const segments = [];

    const parts = text.split(/\[([^\]]+?)\]\((https?:\/\/.*?)\)/g);
    while (parts.length) {
      // Shift off the same number of elements as the pre-split and capture groups.
      const [preambleText, linkText, linkHref] = parts.splice(0, 3);

      if (preambleText) { // Skip empty text as it's an artifact of splitting, not meaningful.
        segments.push({
          isLink: false,
          text: preambleText,
        });
      }

      // Append link if there are any.
      if (linkText && linkHref) {
        segments.push({
          isLink: true,
          text: linkText,
          linkHref,
        });
      }
    }

    return segments;
  }

  /**
   * @param {URL} parsedUrl
   * @param {{numPathParts?: number, preserveQuery?: boolean, preserveHost?: boolean}=} options
   * @return {string}
   */
  static getURLDisplayName(parsedUrl, options) {
    // Closure optional properties aren't optional in tsc, so fallback needs undefined  values.
    options = options || {numPathParts: undefined, preserveQuery: undefined,
      preserveHost: undefined};
    const numPathParts = options.numPathParts !== undefined ? options.numPathParts : 2;
    const preserveQuery = options.preserveQuery !== undefined ? options.preserveQuery : true;
    const preserveHost = options.preserveHost || false;

    let name;

    if (parsedUrl.protocol === 'about:' || parsedUrl.protocol === 'data:') {
      // Handle 'about:*' and 'data:*' URLs specially since they have no path.
      name = parsedUrl.href;
    } else {
      name = parsedUrl.pathname;
      const parts = name.split('/').filter(part => part.length);
      if (numPathParts && parts.length > numPathParts) {
        name = ELLIPSIS + parts.slice(-1 * numPathParts).join('/');
      }

      if (preserveHost) {
        name = `${parsedUrl.host}/${name.replace(/^\//, '')}`;
      }
      if (preserveQuery) {
        name = `${name}${parsedUrl.search}`;
      }
    }

    const MAX_LENGTH = 64;
    // Always elide hexadecimal hash
    name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
    // Also elide other hash-like mixed-case strings
    name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
      `$1${ELLIPSIS}`);
    // Also elide long number sequences
    name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
    // Merge any adjacent ellipses
    name = name.replace(/\u2026+/g, ELLIPSIS);

    // Elide query params first
    if (name.length > MAX_LENGTH && name.includes('?')) {
      // Try to leave the first query parameter intact
      name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);

      // Remove it all if it's still too long
      if (name.length > MAX_LENGTH) {
        name = name.replace(/\?.*/, `?${ELLIPSIS}`);
      }
    }

    // Elide too long names next
    if (name.length > MAX_LENGTH) {
      const dotIndex = name.lastIndexOf('.');
      if (dotIndex >= 0) {
        name = name.slice(0, MAX_LENGTH - 1 - (name.length - dotIndex)) +
          // Show file extension
          `${ELLIPSIS}${name.slice(dotIndex)}`;
      } else {
        name = name.slice(0, MAX_LENGTH - 1) + ELLIPSIS;
      }
    }

    return name;
  }

  /**
   * Split a URL into a file, hostname and origin for easy display.
   * @param {string} url
   * @return {{file: string, hostname: string, origin: string}}
   */
  static parseURL(url) {
    const parsedUrl = new URL(url);
    return {
      file: Util.getURLDisplayName(parsedUrl),
      hostname: parsedUrl.hostname,
      origin: parsedUrl.origin,
    };
  }

  /**
   * @param {string|URL} value
   * @return {URL}
   */
  static createOrReturnURL(value) {
    if (value instanceof URL) {
      return value;
    }

    return new URL(value);
  }

  /**
   * Gets the tld of a domain
   *
   * @param {string} hostname
   * @return {string} tld
   */
  static getTld(hostname) {
    const tlds = hostname.split('.').slice(-2);

    if (!listOfTlds.includes(tlds[0])) {
      return `.${tlds[tlds.length - 1]}`;
    }

    return `.${tlds.join('.')}`;
  }

  /**
   * Returns a primary domain for provided hostname (e.g. www.example.com -> example.com).
   * @param {string|URL} url hostname or URL object
   * @returns {string}
   */
  static getRootDomain(url) {
    const hostname = Util.createOrReturnURL(url).hostname;
    const tld = Util.getTld(hostname);

    // tld is .com or .co.uk which means we means that length is 1 to big
    // .com => 2 & .co.uk => 3
    const splitTld = tld.split('.');

    // get TLD + root domain
    return hostname.split('.').slice(-splitTld.length).join('.');
  }

  /**
   * @param {LH.Config.Settings} settings
   * @return {Array<{name: string, description: string}>}
   */
  static getEnvironmentDisplayValues(settings) {
    const emulationDesc = Util.getEmulationDescriptions(settings);

    return [
      {
        name: 'Device',
        description: emulationDesc.deviceEmulation,
      },
      {
        name: 'Network throttling',
        description: emulationDesc.networkThrottling,
      },
      {
        name: 'CPU throttling',
        description: emulationDesc.cpuThrottling,
      },
    ];
  }

  /**
   * @param {LH.Config.Settings} settings
   * @return {{deviceEmulation: string, networkThrottling: string, cpuThrottling: string, summary: string}}
   */
  static getEmulationDescriptions(settings) {
    let cpuThrottling;
    let networkThrottling;
    let summary;

    const throttling = settings.throttling;

    switch (settings.throttlingMethod) {
      case 'provided':
        cpuThrottling = 'Provided by environment';
        networkThrottling = 'Provided by environment';
        summary = 'No throttling applied';
        break;
      case 'devtools': {
        const {cpuSlowdownMultiplier, requestLatencyMs} = throttling;
        cpuThrottling = `${Util.formatNumber(cpuSlowdownMultiplier)}x slowdown (DevTools)`;
        networkThrottling = `${Util.formatNumber(requestLatencyMs)}${NBSP}ms HTTP RTT, ` +
          `${Util.formatNumber(throttling.downloadThroughputKbps)}${NBSP}Kbps down, ` +
          `${Util.formatNumber(throttling.uploadThroughputKbps)}${NBSP}Kbps up (DevTools)`;
        summary = 'Throttled Slow 4G network';
        break;
      }
      case 'simulate': {
        const {cpuSlowdownMultiplier, rttMs, throughputKbps} = throttling;
        cpuThrottling = `${Util.formatNumber(cpuSlowdownMultiplier)}x slowdown (Simulated)`;
        networkThrottling = `${Util.formatNumber(rttMs)}${NBSP}ms TCP RTT, ` +
          `${Util.formatNumber(throughputKbps)}${NBSP}Kbps throughput (Simulated)`;
        summary = 'Simulated Slow 4G network';
        break;
      }
      default:
        cpuThrottling = 'Unknown';
        networkThrottling = 'Unknown';
        summary = 'Unknown';
    }

    let deviceEmulation = 'No emulation';
    if (settings.emulatedFormFactor === 'mobile') deviceEmulation = 'Emulated Nexus 5X';
    if (settings.emulatedFormFactor === 'desktop') deviceEmulation = 'Emulated Desktop';

    return {
      deviceEmulation,
      cpuThrottling,
      networkThrottling,
      summary: `${deviceEmulation}, ${summary}`,
    };
  }

  /**
   * Set the locale to be used for Util's number and date formatting functions.
   * @param {LH.Locale} locale
   */
  static setNumberDateLocale(locale) {
    // When testing, use a locale with more exciting numeric formatting
    if (locale === 'en-XA') locale = 'de';

    Util.numberDateLocale = locale;
    Util.numberFormatter = new Intl.NumberFormat(locale);
  }

  /**
   * Returns only lines that are near a message, or the first few lines if there are
   * no line messages.
   * @param {LH.Audit.Details.SnippetValue['lines']} lines
   * @param {LH.Audit.Details.SnippetValue['lineMessages']} lineMessages
   * @param {number} surroundingLineCount Number of lines to include before and after
   * the message. If this is e.g. 2 this function might return 5 lines.
   */
  static filterRelevantLines(lines, lineMessages, surroundingLineCount) {
    if (lineMessages.length === 0) {
      // no lines with messages, just return the first bunch of lines
      return lines.slice(0, surroundingLineCount * 2 + 1);
    }

    const minGapSize = 3;
    const lineNumbersToKeep = new Set();
    // Sort messages so we can check lineNumbersToKeep to see how big the gap to
    // the previous line is.
    lineMessages = lineMessages.sort((a, b) => (a.lineNumber || 0) - (b.lineNumber || 0));
    lineMessages.forEach(({lineNumber}) => {
      let firstSurroundingLineNumber = lineNumber - surroundingLineCount;
      let lastSurroundingLineNumber = lineNumber + surroundingLineCount;

      while (firstSurroundingLineNumber < 1) {
        // make sure we still show (surroundingLineCount * 2 + 1) lines in total
        firstSurroundingLineNumber++;
        lastSurroundingLineNumber++;
      }
      // If only a few lines would be omitted normally then we prefer to include
      // extra lines to avoid the tiny gap
      if (lineNumbersToKeep.has(firstSurroundingLineNumber - minGapSize - 1)) {
        firstSurroundingLineNumber -= minGapSize;
      }
      for (let i = firstSurroundingLineNumber; i <= lastSurroundingLineNumber; i++) {
        const surroundingLineNumber = i;
        lineNumbersToKeep.add(surroundingLineNumber);
      }
    });

    return lines.filter(line => lineNumbersToKeep.has(line.lineNumber));
  }

  /**
   * @param {string} categoryId
   */
  static isPluginCategory(categoryId) {
    return categoryId.startsWith('lighthouse-plugin-');
  }
}

/**
 * This value is updated on each run to the locale of the report
 * @type {LH.Locale}
 */
Util.numberDateLocale = 'en';

/**
 * This value stays in sync with Util.numberDateLocale.
 * @type {Intl.NumberFormat}
 */
Util.numberFormatter = new Intl.NumberFormat(Util.numberDateLocale);

/**
 * Report-renderer-specific strings.
 * @type {LH.I18NRendererStrings}
 */
Util.UIStrings = {
  /** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
  varianceDisclaimer: 'Values are estimated and may vary. The performance score is [based only on these metrics](https://github.com/GoogleChrome/lighthouse/blob/d2ec9ffbb21de9ad1a0f86ed24575eda32c796f0/docs/scoring.md#how-are-the-scores-weighted).',
  /** Column heading label for the listing of opportunity audits. Each audit title represents an opportunity. There are only 2 columns, so no strict character limit.  */
  opportunityResourceColumnLabel: 'Opportunity',
  /** Column heading label for the estimated page load savings of opportunity audits. Estimated Savings is the total amount of time (in seconds) that Lighthouse computed could be reduced from the total page load time, if the suggested action is taken. There are only 2 columns, so no strict character limit. */
  opportunitySavingsColumnLabel: 'Estimated Savings',

  /** An error string displayed next to a particular audit when it has errored, but not provided any specific error message. */
  errorMissingAuditInfo: 'Report error: no audit information',
  /** A label, shown next to an audit title or metric title, indicating that there was an error computing it. The user can hover on the label to reveal a tooltip with the extended error message. Translation should be short (< 20 characters). */
  errorLabel: 'Error!',
  /** This label is shown above a bulleted list of warnings. It is shown directly below an audit that produced warnings. Warnings describe situations the user should be aware of, as Lighthouse was unable to complete all the work required on this audit. For example, The 'Unable to decode image (biglogo.jpg)' warning may show up below an image encoding audit. */
  warningHeader: 'Warnings: ',
  /** The tooltip text on an expandable chevron icon. Clicking the icon expands a section to reveal a list of audit results that was hidden by default. */
  auditGroupExpandTooltip: 'Show audits',
  /** Section heading shown above a list of passed audits that contain warnings. Audits under this section do not negatively impact the score, but Lighthouse has generated some potentially actionable suggestions that should be reviewed. This section is expanded by default and displays after the failing audits. */
  warningAuditsGroupTitle: 'Passed audits but with warnings',
  /** Section heading shown above a list of audits that are passing. 'Passed' here refers to a passing grade. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list. */
  passedAuditsGroupTitle: 'Passed audits',
  /** Section heading shown above a list of audits that do not apply to the page. For example, if an audit is 'Are images optimized?', but the page has no images on it, the audit will be marked as not applicable. This is neither passing or failing. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list. */
  notApplicableAuditsGroupTitle: 'Not applicable',
  /** Section heading shown above a list of audits that were not computed by Lighthouse. They serve as a list of suggestions for the user to go and manually check. For example, Lighthouse can't automate testing cross-browser compatibility, so that is listed within this section, so the user is reminded to test it themselves. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list. */
  manualAuditsGroupTitle: 'Additional items to manually check',

  /** Label shown preceding any important warnings that may have invalidated the entire report. For example, if the user has Chrome extensions installed, they may add enough performance overhead that Lighthouse's performance metrics are unreliable. If shown, this will be displayed at the top of the report UI. */
  toplevelWarningsMessage: 'There were issues affecting this run of Lighthouse:',

  /** String of text shown in a graphical representation of the flow of network requests for the web page. This label represents the initial network request that fetches an HTML page. This navigation may be redirected (eg. Initial navigation to http://example.com redirects to https://www.example.com). */
  crcInitialNavigation: 'Initial Navigation',
  /** Label of value shown in the summary of critical request chains. Refers to the total amount of time (milliseconds) of the longest critical path chain/sequence of network requests. Example value: 2310 ms */
  crcLongestDurationLabel: 'Maximum critical path latency:',

  /** Label for button that shows all lines of the snippet when clicked */
  snippetExpandButtonLabel: 'Expand snippet',
  /** Label for button that only shows a few lines of the snippet when clicked */
  snippetCollapseButtonLabel: 'Collapse snippet',

  /** Explanation shown to users below performance results to inform them that the test was done with a 4G network connection and to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. 'Lighthouse' becomes link text to additional documentation. */
  lsPerformanceCategoryDescription: '[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.',
  /** Title of the lab data section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. "Lab" is an abbreviated form of "laboratory", and refers to the fact that the data is from a controlled test of a website, not measurements from real users visiting that site.  */
  labDataTitle: 'Lab Data',

  /** This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or "3rd-party") resources in the table, where "third-party resources" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page. */
  thirdPartyResourcesLabel: 'Show 3rd-party resources',
};

if (typeof module !== 'undefined' && module.exports) {
  module.exports = Util;
} else {
  self.Util = Util;
}
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* globals URL self Util */

/** @typedef {HTMLElementTagNameMap & {[id: string]: HTMLElement}} HTMLElementByTagName */

class DOM {
  /**
   * @param {Document} document
   */
  constructor(document) {
    /** @type {Document} */
    this._document = document;
    /** @type {string} */
    this._lighthouseChannel = 'unknown';
  }

  /**
   * @template {string} T
   * @param {T} name
   * @param {string=} className
   * @param {Object<string, (string|undefined)>=} attrs Attribute key/val pairs.
   *     Note: if an attribute key has an undefined value, this method does not
   *     set the attribute on the node.
   * @return {HTMLElementByTagName[T]}
   */
  createElement(name, className, attrs = {}) {
    const element = this._document.createElement(name);
    if (className) {
      element.className = className;
    }
    Object.keys(attrs).forEach(key => {
      const value = attrs[key];
      if (typeof value !== 'undefined') {
        element.setAttribute(key, value);
      }
    });
    return element;
  }

  /**
   * @return {DocumentFragment}
   */
  createFragment() {
    return this._document.createDocumentFragment();
  }

  /**
   * @template {string} T
   * @param {Element} parentElem
   * @param {T} elementName
   * @param {string=} className
   * @param {Object<string, (string|undefined)>=} attrs Attribute key/val pairs.
   *     Note: if an attribute key has an undefined value, this method does not
   *     set the attribute on the node.
   * @return {HTMLElementByTagName[T]}
   */
  createChildOf(parentElem, elementName, className, attrs) {
    const element = this.createElement(elementName, className, attrs);
    parentElem.appendChild(element);
    return element;
  }

  /**
   * @param {string} selector
   * @param {ParentNode} context
   * @return {DocumentFragment} A clone of the template content.
   * @throws {Error}
   */
  cloneTemplate(selector, context) {
    const template = /** @type {?HTMLTemplateElement} */ (context.querySelector(selector));
    if (!template) {
      throw new Error(`Template not found: template${selector}`);
    }

    const clone = this._document.importNode(template.content, true);

    // Prevent duplicate styles in the DOM. After a template has been stamped
    // for the first time, remove the clone's styles so they're not re-added.
    if (template.hasAttribute('data-stamped')) {
      this.findAll('style', clone).forEach(style => style.remove());
    }
    template.setAttribute('data-stamped', 'true');

    return clone;
  }

  /**
   * Resets the "stamped" state of the templates.
   */
  resetTemplates() {
    this.findAll('template[data-stamped]', this._document).forEach(t => {
      t.removeAttribute('data-stamped');
    });
  }

  /**
   * @param {string} text
   * @return {Element}
   */
  convertMarkdownLinkSnippets(text) {
    const element = this.createElement('span');

    for (const segment of Util.splitMarkdownLink(text)) {
      if (!segment.isLink) {
        // Plain text segment.
        element.appendChild(this._document.createTextNode(segment.text));
        continue;
      }

      // Otherwise, append any links found.
      const url = new URL(segment.linkHref);

      const DOCS_ORIGINS = ['https://developers.google.com', 'https://web.dev'];
      if (DOCS_ORIGINS.includes(url.origin)) {
        url.searchParams.set('utm_source', 'lighthouse');
        url.searchParams.set('utm_medium', this._lighthouseChannel);
      }

      const a = this.createElement('a');
      a.rel = 'noopener';
      a.target = '_blank';
      a.textContent = segment.text;
      a.href = url.href;
      element.appendChild(a);
    }

    return element;
  }

  /**
   * @param {string} markdownText
   * @return {Element}
   */
  convertMarkdownCodeSnippets(markdownText) {
    const element = this.createElement('span');

    for (const segment of Util.splitMarkdownCodeSpans(markdownText)) {
      if (segment.isCode) {
        const pre = this.createElement('code');
        pre.textContent = segment.text;
        element.appendChild(pre);
      } else {
        element.appendChild(this._document.createTextNode(segment.text));
      }
    }

    return element;
  }

  /**
   * The channel to use for UTM data when rendering links to the documentation.
   * @param {string} lighthouseChannel
   */
  setLighthouseChannel(lighthouseChannel) {
    this._lighthouseChannel = lighthouseChannel;
  }

  /**
   * @return {Document}
   */
  document() {
    return this._document;
  }

  /**
   * TODO(paulirish): import and conditionally apply the DevTools frontend subclasses instead of this
   * @return {boolean}
   */
  isDevTools() {
    return !!this._document.querySelector('.lh-devtools');
  }

  /**
   * Guaranteed context.querySelector. Always returns an element or throws if
   * nothing matches query.
   * @param {string} query
   * @param {ParentNode} context
   * @return {HTMLElement}
   */
  find(query, context) {
    /** @type {?HTMLElement} */
    const result = context.querySelector(query);
    if (result === null) {
      throw new Error(`query ${query} not found`);
    }
    return result;
  }

  /**
   * Helper for context.querySelectorAll. Returns an Array instead of a NodeList.
   * @param {string} query
   * @param {ParentNode} context
   * @return {Array<HTMLElement>}
   */
  findAll(query, context) {
    return Array.from(context.querySelectorAll(query));
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = DOM;
} else {
  self.DOM = DOM;
}
;
/*
Details Element Polyfill 2.4.0
Copyright © 2019 Javan Makhmali
 */
(function() {
  "use strict";
  var element = document.createElement("details");
  var elementIsNative = typeof HTMLDetailsElement != "undefined" && element instanceof HTMLDetailsElement;
  var support = {
    open: "open" in element || elementIsNative,
    toggle: "ontoggle" in element
  };
  var styles = '\ndetails, summary {\n  display: block;\n}\ndetails:not([open]) > *:not(summary) {\n  display: none;\n}\nsummary::before {\n  content: "►";\n  padding-right: 0.3rem;\n  font-size: 0.6rem;\n  cursor: default;\n}\n[open] > summary::before {\n  content: "▼";\n}\n';
  var _ref = [], forEach = _ref.forEach, slice = _ref.slice;
  if (!support.open) {
    polyfillStyles();
    polyfillProperties();
    polyfillToggle();
    polyfillAccessibility();
  }
  if (support.open && !support.toggle) {
    polyfillToggleEvent();
  }
  function polyfillStyles() {
    document.head.insertAdjacentHTML("afterbegin", "<style>" + styles + "\u003c/style>");
  }
  function polyfillProperties() {
    var prototype = document.createElement("details").constructor.prototype;
    var setAttribute = prototype.setAttribute, removeAttribute = prototype.removeAttribute;
    var open = Object.getOwnPropertyDescriptor(prototype, "open");
    Object.defineProperties(prototype, {
      open: {
        get: function get() {
          if (this.tagName == "DETAILS") {
            return this.hasAttribute("open");
          } else {
            if (open && open.get) {
              return open.get.call(this);
            }
          }
        },
        set: function set(value) {
          if (this.tagName == "DETAILS") {
            return value ? this.setAttribute("open", "") : this.removeAttribute("open");
          } else {
            if (open && open.set) {
              return open.set.call(this, value);
            }
          }
        }
      },
      setAttribute: {
        value: function value(name, _value) {
          var _this = this;
          var call = function call() {
            return setAttribute.call(_this, name, _value);
          };
          if (name == "open" && this.tagName == "DETAILS") {
            var wasOpen = this.hasAttribute("open");
            var result = call();
            if (!wasOpen) {
              var summary = this.querySelector("summary");
              if (summary) summary.setAttribute("aria-expanded", true);
              triggerToggle(this);
            }
            return result;
          }
          return call();
        }
      },
      removeAttribute: {
        value: function value(name) {
          var _this2 = this;
          var call = function call() {
            return removeAttribute.call(_this2, name);
          };
          if (name == "open" && this.tagName == "DETAILS") {
            var wasOpen = this.hasAttribute("open");
            var result = call();
            if (wasOpen) {
              var summary = this.querySelector("summary");
              if (summary) summary.setAttribute("aria-expanded", false);
              triggerToggle(this);
            }
            return result;
          }
          return call();
        }
      }
    });
  }
  function polyfillToggle() {
    onTogglingTrigger(function(element) {
      element.hasAttribute("open") ? element.removeAttribute("open") : element.setAttribute("open", "");
    });
  }
  function polyfillToggleEvent() {
    if (window.MutationObserver) {
      new MutationObserver(function(mutations) {
        forEach.call(mutations, function(mutation) {
          var target = mutation.target, attributeName = mutation.attributeName;
          if (target.tagName == "DETAILS" && attributeName == "open") {
            triggerToggle(target);
          }
        });
      }).observe(document.documentElement, {
        attributes: true,
        subtree: true
      });
    } else {
      onTogglingTrigger(function(element) {
        var wasOpen = element.getAttribute("open");
        setTimeout(function() {
          var isOpen = element.getAttribute("open");
          if (wasOpen != isOpen) {
            triggerToggle(element);
          }
        }, 1);
      });
    }
  }
  function polyfillAccessibility() {
    setAccessibilityAttributes(document);
    if (window.MutationObserver) {
      new MutationObserver(function(mutations) {
        forEach.call(mutations, function(mutation) {
          forEach.call(mutation.addedNodes, setAccessibilityAttributes);
        });
      }).observe(document.documentElement, {
        subtree: true,
        childList: true
      });
    } else {
      document.addEventListener("DOMNodeInserted", function(event) {
        setAccessibilityAttributes(event.target);
      });
    }
  }
  function setAccessibilityAttributes(root) {
    findElementsWithTagName(root, "SUMMARY").forEach(function(summary) {
      var details = findClosestElementWithTagName(summary, "DETAILS");
      summary.setAttribute("aria-expanded", details.hasAttribute("open"));
      if (!summary.hasAttribute("tabindex")) summary.setAttribute("tabindex", "0");
      if (!summary.hasAttribute("role")) summary.setAttribute("role", "button");
    });
  }
  function eventIsSignificant(event) {
    return !(event.defaultPrevented || event.ctrlKey || event.metaKey || event.shiftKey || event.target.isContentEditable);
  }
  function onTogglingTrigger(callback) {
    addEventListener("click", function(event) {
      if (eventIsSignificant(event)) {
        if (event.which <= 1) {
          var element = findClosestElementWithTagName(event.target, "SUMMARY");
          if (element && element.parentNode && element.parentNode.tagName == "DETAILS") {
            callback(element.parentNode);
          }
        }
      }
    }, false);
    addEventListener("keydown", function(event) {
      if (eventIsSignificant(event)) {
        if (event.keyCode == 13 || event.keyCode == 32) {
          var element = findClosestElementWithTagName(event.target, "SUMMARY");
          if (element && element.parentNode && element.parentNode.tagName == "DETAILS") {
            callback(element.parentNode);
            event.preventDefault();
          }
        }
      }
    }, false);
  }
  function triggerToggle(element) {
    var event = document.createEvent("Event");
    event.initEvent("toggle", false, false);
    element.dispatchEvent(event);
  }
  function findElementsWithTagName(root, tagName) {
    return (root.tagName == tagName ? [ root ] : []).concat(typeof root.getElementsByTagName == "function" ? slice.call(root.getElementsByTagName(tagName)) : []);
  }
  function findClosestElementWithTagName(element, tagName) {
    if (typeof element.closest == "function") {
      return element.closest(tagName);
    } else {
      while (element) {
        if (element.tagName == tagName) {
          return element;
        } else {
          element = element.parentNode;
        }
      }
    }
  }
})();
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* globals self CriticalRequestChainRenderer SnippetRenderer Util URL */

/** @typedef {import('./dom.js')} DOM */

const URL_PREFIXES = ['http://', 'https://', 'data:'];

class DetailsRenderer {
  /**
   * @param {DOM} dom
   */
  constructor(dom) {
    /** @type {DOM} */
    this._dom = dom;
    /** @type {ParentNode} */
    this._templateContext; // eslint-disable-line no-unused-expressions
  }

  /**
   * @param {ParentNode} context
   */
  setTemplateContext(context) {
    this._templateContext = context;
  }

  /**
   * @param {LH.Audit.Details} details
   * @return {Element|null}
   */
  render(details) {
    switch (details.type) {
      case 'filmstrip':
        return this._renderFilmstrip(details);
      case 'list':
        return this._renderList(details);
      case 'table':
        return this._renderTable(details);
      case 'criticalrequestchain':
        return CriticalRequestChainRenderer.render(this._dom, this._templateContext, details, this);
      case 'opportunity':
        return this._renderTable(details);

      // Internal-only details, not for rendering.
      case 'screenshot':
      case 'debugdata':
        return null;

      default: {
        // @ts-ignore tsc thinks this is unreachable, but be forward compatible
        // with new unexpected detail types.
        return this._renderUnknown(details.type, details);
      }
    }
  }

  /**
   * @param {{value: number, granularity?: number}} details
   * @return {Element}
   */
  _renderBytes(details) {
    // TODO: handle displayUnit once we have something other than 'kb'
    const value = Util.formatBytesToKB(details.value, details.granularity);
    return this._renderText(value);
  }

  /**
   * @param {{value: number, granularity?: number, displayUnit?: string}} details
   * @return {Element}
   */
  _renderMilliseconds(details) {
    let value = Util.formatMilliseconds(details.value, details.granularity);
    if (details.displayUnit === 'duration') {
      value = Util.formatDuration(details.value);
    }

    return this._renderText(value);
  }

  /**
   * @param {string} text
   * @return {HTMLElement}
   */
  renderTextURL(text) {
    const url = text;

    let displayedPath;
    let displayedHost;
    let title;
    try {
      const parsed = Util.parseURL(url);
      displayedPath = parsed.file === '/' ? parsed.origin : parsed.file;
      displayedHost = parsed.file === '/' ? '' : `(${parsed.hostname})`;
      title = url;
    } catch (e) {
      displayedPath = url;
    }

    const element = this._dom.createElement('div', 'lh-text__url');
    element.appendChild(this._renderLink({text: displayedPath, url}));

    if (displayedHost) {
      const hostElem = this._renderText(displayedHost);
      hostElem.classList.add('lh-text__url-host');
      element.appendChild(hostElem);
    }

    if (title) {
      element.title = url;
      // set the url on the element's dataset which we use to check 3rd party origins
      element.dataset.url = url;
    }
    return element;
  }

  /**
   * @param {{text: string, url: string}} details
   * @return {Element}
   */
  _renderLink(details) {
    const allowedProtocols = ['https:', 'http:'];
    let url;
    try {
      url = new URL(details.url);
    } catch (_) {}

    if (!url || !allowedProtocols.includes(url.protocol)) {
      // Fall back to just the link text if invalid or protocol not allowed.
      return this._renderText(details.text);
    }

    const a = this._dom.createElement('a');
    a.rel = 'noopener';
    a.target = '_blank';
    a.textContent = details.text;
    a.href = url.href;

    return a;
  }

  /**
   * @param {string} text
   * @return {Element}
   */
  _renderText(text) {
    const element = this._dom.createElement('div', 'lh-text');
    element.textContent = text;
    return element;
  }

  /**
   * @param {string} text
   * @return {Element}
   */
  _renderNumeric(text) {
    const element = this._dom.createElement('div', 'lh-numeric');
    element.textContent = text;
    return element;
  }

  /**
   * Create small thumbnail with scaled down image asset.
   * @param {string} details
   * @return {Element}
   */
  _renderThumbnail(details) {
    const element = this._dom.createElement('img', 'lh-thumbnail');
    const strValue = details;
    element.src = strValue;
    element.title = strValue;
    element.alt = '';
    return element;
  }

  /**
   * @param {string} type
   * @param {*} value
   */
  _renderUnknown(type, value) {
    // eslint-disable-next-line no-console
    console.error(`Unknown details type: ${type}`, value);
    const element = this._dom.createElement('details', 'lh-unknown');
    this._dom.createChildOf(element, 'summary').textContent =
      `We don't know how to render audit details of type \`${type}\`. ` +
      'The Lighthouse version that collected this data is likely newer than the Lighthouse ' +
      'version of the report renderer. Expand for the raw JSON.';
    this._dom.createChildOf(element, 'pre').textContent = JSON.stringify(value, null, 2);
    return element;
  }

  /**
   * Render a details item value for embedding in a table. Renders the value
   * based on the heading's valueType, unless the value itself has a `type`
   * property to override it.
   * @param {LH.Audit.Details.TableItem[string] | LH.Audit.Details.OpportunityItem[string]} value
   * @param {LH.Audit.Details.OpportunityColumnHeading} heading
   * @return {Element|null}
   */
  _renderTableValue(value, heading) {
    if (typeof value === 'undefined' || value === null) {
      return null;
    }

    // First deal with the possible object forms of value.
    if (typeof value === 'object') {
      // The value's type overrides the heading's for this column.
      switch (value.type) {
        case 'code': {
          return this._renderCode(value.value);
        }
        case 'link': {
          return this._renderLink(value);
        }
        case 'node': {
          return this.renderNode(value);
        }
        case 'url': {
          return this.renderTextURL(value.value);
        }
        default: {
          return this._renderUnknown(value.type, value);
        }
      }
    }

    // Next, deal with primitives.
    switch (heading.valueType) {
      case 'bytes': {
        const numValue = Number(value);
        return this._renderBytes({value: numValue, granularity: 1});
      }
      case 'code': {
        const strValue = String(value);
        return this._renderCode(strValue);
      }
      case 'ms': {
        const msValue = {
          value: Number(value),
          granularity: heading.granularity,
          displayUnit: heading.displayUnit,
        };
        return this._renderMilliseconds(msValue);
      }
      case 'numeric': {
        const strValue = String(value);
        return this._renderNumeric(strValue);
      }
      case 'text': {
        const strValue = String(value);
        return this._renderText(strValue);
      }
      case 'thumbnail': {
        const strValue = String(value);
        return this._renderThumbnail(strValue);
      }
      case 'timespanMs': {
        const numValue = Number(value);
        return this._renderMilliseconds({value: numValue});
      }
      case 'url': {
        const strValue = String(value);
        if (URL_PREFIXES.some(prefix => strValue.startsWith(prefix))) {
          return this.renderTextURL(strValue);
        } else {
          // Fall back to <pre> rendering if not actually a URL.
          return this._renderCode(strValue);
        }
      }
      default: {
        return this._renderUnknown(heading.valueType, value);
      }
    }
  }

  /**
   * Get the headings of a table-like details object, converted into the
   * OpportunityColumnHeading type until we have all details use the same
   * heading format.
   * @param {LH.Audit.Details.Table|LH.Audit.Details.Opportunity} tableLike
   * @return {Array<LH.Audit.Details.OpportunityColumnHeading>} header
   */
  _getCanonicalizedTableHeadings(tableLike) {
    if (tableLike.type === 'opportunity') {
      return tableLike.headings;
    }

    return tableLike.headings.map(heading => {
      return {
        key: heading.key,
        label: heading.text,
        valueType: heading.itemType,
        displayUnit: heading.displayUnit,
        granularity: heading.granularity,
      };
    });
  }

  /**
   * @param {LH.Audit.Details.Table|LH.Audit.Details.Opportunity} details
   * @return {Element}
   */
  _renderTable(details) {
    if (!details.items.length) return this._dom.createElement('span');

    const tableElem = this._dom.createElement('table', 'lh-table');
    const theadElem = this._dom.createChildOf(tableElem, 'thead');
    const theadTrElem = this._dom.createChildOf(theadElem, 'tr');

    const headings = this._getCanonicalizedTableHeadings(details);

    for (const heading of headings) {
      const valueType = heading.valueType || 'text';
      const classes = `lh-table-column--${valueType}`;
      const labelEl = this._dom.createElement('div', 'lh-text');
      labelEl.textContent = heading.label;
      this._dom.createChildOf(theadTrElem, 'th', classes).appendChild(labelEl);
    }

    const tbodyElem = this._dom.createChildOf(tableElem, 'tbody');
    for (const row of details.items) {
      const rowElem = this._dom.createChildOf(tbodyElem, 'tr');
      for (const heading of headings) {
        const value = row[heading.key];
        const valueElement = this._renderTableValue(value, heading);

        if (valueElement) {
          const classes = `lh-table-column--${heading.valueType}`;
          this._dom.createChildOf(rowElem, 'td', classes).appendChild(valueElement);
        } else {
          this._dom.createChildOf(rowElem, 'td', 'lh-table-column--empty');
        }
      }
    }
    return tableElem;
  }

  /**
   * @param {LH.Audit.Details.List} details
   * @return {Element}
   */
  _renderList(details) {
    const listContainer = this._dom.createElement('div', 'lh-list');

    details.items.forEach(item => {
      const snippetEl = SnippetRenderer.render(this._dom, this._templateContext, item, this);
      listContainer.appendChild(snippetEl);
    });

    return listContainer;
  }

  /**
   * @param {LH.Audit.Details.NodeValue} item
   * @return {Element}
   * @protected
   */
  renderNode(item) {
    const element = this._dom.createElement('span', 'lh-node');
    if (item.nodeLabel) {
      const nodeLabelEl = this._dom.createElement('div');
      nodeLabelEl.textContent = item.nodeLabel;
      element.appendChild(nodeLabelEl);
    }
    if (item.snippet) {
      const snippetEl = this._dom.createElement('div');
      snippetEl.classList.add('lh-node__snippet');
      snippetEl.textContent = item.snippet;
      element.appendChild(snippetEl);
    }
    if (item.selector) {
      element.title = item.selector;
    }
    if (item.path) element.setAttribute('data-path', item.path);
    if (item.selector) element.setAttribute('data-selector', item.selector);
    if (item.snippet) element.setAttribute('data-snippet', item.snippet);

    return element;
  }

  /**
   * @param {LH.Audit.Details.Filmstrip} details
   * @return {Element}
   */
  _renderFilmstrip(details) {
    const filmstripEl = this._dom.createElement('div', 'lh-filmstrip');

    for (const thumbnail of details.items) {
      const frameEl = this._dom.createChildOf(filmstripEl, 'div', 'lh-filmstrip__frame');
      this._dom.createChildOf(frameEl, 'img', 'lh-filmstrip__thumbnail', {
        src: thumbnail.data,
        alt: `Screenshot`,
      });
    }
    return filmstripEl;
  }

  /**
   * @param {string} text
   * @return {Element}
   */
  _renderCode(text) {
    const pre = this._dom.createElement('pre', 'lh-code');
    pre.textContent = text;
    return pre;
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = DetailsRenderer;
} else {
  self.DetailsRenderer = DetailsRenderer;
}
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/**
 * @fileoverview This file contains helpers for constructing and rendering the
 * critical request chains network tree.
 */

/* globals self Util */

/** @typedef {import('./dom.js')} DOM */

class CriticalRequestChainRenderer {
  /**
   * Create render context for critical-request-chain tree display.
   * @param {LH.Audit.SimpleCriticalRequestNode} tree
   * @return {{tree: LH.Audit.SimpleCriticalRequestNode, startTime: number, transferSize: number}}
   */
  static initTree(tree) {
    let startTime = 0;
    const rootNodes = Object.keys(tree);
    if (rootNodes.length > 0) {
      const node = tree[rootNodes[0]];
      startTime = node.request.startTime;
    }

    return {tree, startTime, transferSize: 0};
  }

  /**
   * Helper to create context for each critical-request-chain node based on its
   * parent. Calculates if this node is the last child, whether it has any
   * children itself and what the tree looks like all the way back up to the root,
   * so the tree markers can be drawn correctly.
   * @param {LH.Audit.SimpleCriticalRequestNode} parent
   * @param {string} id
   * @param {number} startTime
   * @param {number} transferSize
   * @param {Array<boolean>=} treeMarkers
   * @param {boolean=} parentIsLastChild
   * @return {CRCSegment}
   */
  static createSegment(parent, id, startTime, transferSize, treeMarkers, parentIsLastChild) {
    const node = parent[id];
    const siblings = Object.keys(parent);
    const isLastChild = siblings.indexOf(id) === (siblings.length - 1);
    const hasChildren = !!node.children && Object.keys(node.children).length > 0;

    // Copy the tree markers so that we don't change by reference.
    const newTreeMarkers = Array.isArray(treeMarkers) ? treeMarkers.slice(0) : [];

    // Add on the new entry.
    if (typeof parentIsLastChild !== 'undefined') {
      newTreeMarkers.push(!parentIsLastChild);
    }

    return {
      node,
      isLastChild,
      hasChildren,
      startTime,
      transferSize: transferSize + node.request.transferSize,
      treeMarkers: newTreeMarkers,
    };
  }

  /**
   * Creates the DOM for a tree segment.
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {CRCSegment} segment
   * @param {DetailsRenderer} detailsRenderer
   * @return {Node}
   */
  static createChainNode(dom, tmpl, segment, detailsRenderer) {
    const chainsEl = dom.cloneTemplate('#tmpl-lh-crc__chains', tmpl);

    // Hovering over request shows full URL.
    dom.find('.crc-node', chainsEl).setAttribute('title', segment.node.request.url);

    const treeMarkeEl = dom.find('.crc-node__tree-marker', chainsEl);

    // Construct lines and add spacers for sub requests.
    segment.treeMarkers.forEach(separator => {
      if (separator) {
        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker vert'));
        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker'));
      } else {
        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker'));
        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker'));
      }
    });

    if (segment.isLastChild) {
      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker up-right'));
      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker right'));
    } else {
      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker vert-right'));
      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker right'));
    }

    if (segment.hasChildren) {
      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker horiz-down'));
    } else {
      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker right'));
    }

    // Fill in url, host, and request size information.
    const url = segment.node.request.url;
    const linkEl = detailsRenderer.renderTextURL(url);
    const treevalEl = dom.find('.crc-node__tree-value', chainsEl);
    treevalEl.appendChild(linkEl);

    if (!segment.hasChildren) {
      const {startTime, endTime, transferSize} = segment.node.request;
      const span = dom.createElement('span', 'crc-node__chain-duration');
      span.textContent = ' - ' + Util.formatMilliseconds((endTime - startTime) * 1000) + ', ';
      const span2 = dom.createElement('span', 'crc-node__chain-duration');
      span2.textContent = Util.formatBytesToKB(transferSize, 0.01);

      treevalEl.appendChild(span);
      treevalEl.appendChild(span2);
    }

    return chainsEl;
  }

  /**
   * Recursively builds a tree from segments.
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {CRCSegment} segment
   * @param {Element} elem Parent element.
   * @param {LH.Audit.Details.CriticalRequestChain} details
   * @param {DetailsRenderer} detailsRenderer
   */
  static buildTree(dom, tmpl, segment, elem, details, detailsRenderer) {
    elem.appendChild(CRCRenderer.createChainNode(dom, tmpl, segment, detailsRenderer));
    if (segment.node.children) {
      for (const key of Object.keys(segment.node.children)) {
        const childSegment = CRCRenderer.createSegment(segment.node.children, key,
          segment.startTime, segment.transferSize, segment.treeMarkers, segment.isLastChild);
        CRCRenderer.buildTree(dom, tmpl, childSegment, elem, details, detailsRenderer);
      }
    }
  }

  /**
   * @param {DOM} dom
   * @param {ParentNode} templateContext
   * @param {LH.Audit.Details.CriticalRequestChain} details
   * @param {DetailsRenderer} detailsRenderer
   * @return {Element}
   */
  static render(dom, templateContext, details, detailsRenderer) {
    const tmpl = dom.cloneTemplate('#tmpl-lh-crc', templateContext);
    const containerEl = dom.find('.lh-crc', tmpl);

    // Fill in top summary.
    dom.find('.crc-initial-nav', tmpl).textContent = Util.UIStrings.crcInitialNavigation;
    dom.find('.lh-crc__longest_duration_label', tmpl).textContent =
        Util.UIStrings.crcLongestDurationLabel;
    dom.find('.lh-crc__longest_duration', tmpl).textContent =
        Util.formatMilliseconds(details.longestChain.duration);

    // Construct visual tree.
    const root = CRCRenderer.initTree(details.chains);
    for (const key of Object.keys(root.tree)) {
      const segment = CRCRenderer.createSegment(root.tree, key, root.startTime, root.transferSize);
      CRCRenderer.buildTree(dom, tmpl, segment, containerEl, details, detailsRenderer);
    }

    return dom.find('.lh-crc-container', tmpl);
  }
}

// Alias b/c the name is really long.
const CRCRenderer = CriticalRequestChainRenderer;

// Allow Node require()'ing.
if (typeof module !== 'undefined' && module.exports) {
  module.exports = CriticalRequestChainRenderer;
} else {
  self.CriticalRequestChainRenderer = CriticalRequestChainRenderer;
}

/** @typedef {{
      node: LH.Audit.SimpleCriticalRequestNode[string],
      isLastChild: boolean,
      hasChildren: boolean,
      startTime: number,
      transferSize: number,
      treeMarkers: Array<boolean>
  }} CRCSegment
 */
;
/**
 * @license Copyright 2019 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */
'use strict';

/* globals self, Util */

/** @typedef {import('./details-renderer')} DetailsRenderer */

/** @enum {number} */
const LineVisibility = {
  /** Show regardless of whether the snippet is collapsed or expanded */
  ALWAYS: 0,
  WHEN_COLLAPSED: 1,
  WHEN_EXPANDED: 2,
};

/** @enum {number} */
const LineContentType = {
  /** A line of content */
  CONTENT_NORMAL: 0,
  /** A line of content that's emphasized by setting the CSS background color */
  CONTENT_HIGHLIGHTED: 1,
  /** Use when some lines are hidden, shows the "..." placeholder */
  PLACEHOLDER: 2,
  /** A message about a line of content or the snippet in general */
  MESSAGE: 3,
};

/** @typedef {{
    content: string;
    lineNumber: string | number;
    contentType: LineContentType;
    truncated?: boolean;
    visibility?: LineVisibility;
}} LineDetails */

const classNamesByContentType = {
  [LineContentType.CONTENT_NORMAL]: ['lh-snippet__line--content'],
  [LineContentType.CONTENT_HIGHLIGHTED]: [
    'lh-snippet__line--content',
    'lh-snippet__line--content-highlighted',
  ],
  [LineContentType.PLACEHOLDER]: ['lh-snippet__line--placeholder'],
  [LineContentType.MESSAGE]: ['lh-snippet__line--message'],
};

/**
 * @param {LH.Audit.Details.SnippetValue['lines']} lines
 * @param {number} lineNumber
 * @return {{line?: LH.Audit.Details.SnippetValue['lines'][0], previousLine?: LH.Audit.Details.SnippetValue['lines'][0]}}
 */
function getLineAndPreviousLine(lines, lineNumber) {
  return {
    line: lines.find(l => l.lineNumber === lineNumber),
    previousLine: lines.find(l => l.lineNumber === lineNumber - 1),
  };
}

/**
 * @param {LH.Audit.Details.SnippetValue["lineMessages"]} messages
 * @param {number} lineNumber
 */
function getMessagesForLineNumber(messages, lineNumber) {
  return messages.filter(h => h.lineNumber === lineNumber);
}

/**
 * @param {LH.Audit.Details.SnippetValue} details
 * @return {LH.Audit.Details.SnippetValue['lines']}
 */
function getLinesWhenCollapsed(details) {
  const SURROUNDING_LINES_TO_SHOW_WHEN_COLLAPSED = 2;
  return Util.filterRelevantLines(
    details.lines,
    details.lineMessages,
    SURROUNDING_LINES_TO_SHOW_WHEN_COLLAPSED
  );
}

/**
 * Render snippet of text with line numbers and annotations.
 * By default we only show a few lines around each annotation and the user
 * can click "Expand snippet" to show more.
 * Content lines with annotations are highlighted.
 */
class SnippetRenderer {
  /**
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {LH.Audit.Details.SnippetValue} details
   * @param {DetailsRenderer} detailsRenderer
   * @param {function} toggleExpandedFn
   * @return {DocumentFragment}
   */
  static renderHeader(dom, tmpl, details, detailsRenderer, toggleExpandedFn) {
    const linesWhenCollapsed = getLinesWhenCollapsed(details);
    const canExpand = linesWhenCollapsed.length < details.lines.length;

    const header = dom.cloneTemplate('#tmpl-lh-snippet__header', tmpl);
    dom.find('.lh-snippet__title', header).textContent = details.title;

    const {
      snippetCollapseButtonLabel,
      snippetExpandButtonLabel,
    } = Util.UIStrings;
    dom.find(
      '.lh-snippet__btn-label-collapse',
      header
    ).textContent = snippetCollapseButtonLabel;
    dom.find(
      '.lh-snippet__btn-label-expand',
      header
    ).textContent = snippetExpandButtonLabel;

    const toggleExpandButton = dom.find('.lh-snippet__toggle-expand', header);
    // If we're already showing all the available lines of the snippet, we don't need an
    // expand/collapse button and can remove it from the DOM.
    // If we leave the button in though, wire up the click listener to toggle visibility!
    if (!canExpand) {
      toggleExpandButton.remove();
    } else {
      toggleExpandButton.addEventListener('click', () => toggleExpandedFn());
    }

    // We only show the source node of the snippet in DevTools because then the user can
    // access the full element detail. Just being able to see the outer HTML isn't very useful.
    if (details.node && dom.isDevTools()) {
      const nodeContainer = dom.find('.lh-snippet__node', header);
      nodeContainer.appendChild(detailsRenderer.renderNode(details.node));
    }

    return header;
  }

  /**
   * Renders a line (text content, message, or placeholder) as a DOM element.
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {LineDetails} lineDetails
   * @return {Element}
   */
  static renderSnippetLine(
      dom,
      tmpl,
      {content, lineNumber, truncated, contentType, visibility}
  ) {
    const clonedTemplate = dom.cloneTemplate('#tmpl-lh-snippet__line', tmpl);
    const contentLine = dom.find('.lh-snippet__line', clonedTemplate);
    const {classList} = contentLine;

    classNamesByContentType[contentType].forEach(typeClass =>
      classList.add(typeClass)
    );

    if (visibility === LineVisibility.WHEN_COLLAPSED) {
      classList.add('lh-snippet__show-if-collapsed');
    } else if (visibility === LineVisibility.WHEN_EXPANDED) {
      classList.add('lh-snippet__show-if-expanded');
    }

    const lineContent = content + (truncated ? '…' : '');
    const lineContentEl = dom.find('.lh-snippet__line code', contentLine);
    if (contentType === LineContentType.MESSAGE) {
      lineContentEl.appendChild(dom.convertMarkdownLinkSnippets(lineContent));
    } else {
      lineContentEl.textContent = lineContent;
    }

    dom.find(
      '.lh-snippet__line-number',
      contentLine
    ).textContent = lineNumber.toString();

    return contentLine;
  }

  /**
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {{message: string}} message
   * @return {Element}
   */
  static renderMessage(dom, tmpl, message) {
    return SnippetRenderer.renderSnippetLine(dom, tmpl, {
      lineNumber: ' ',
      content: message.message,
      contentType: LineContentType.MESSAGE,
    });
  }

  /**
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {LineVisibility} visibility
   * @return {Element}
   */
  static renderOmittedLinesPlaceholder(dom, tmpl, visibility) {
    return SnippetRenderer.renderSnippetLine(dom, tmpl, {
      lineNumber: '…',
      content: '',
      visibility,
      contentType: LineContentType.PLACEHOLDER,
    });
  }

  /**
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {LH.Audit.Details.SnippetValue} details
   * @return {DocumentFragment}
   */
  static renderSnippetContent(dom, tmpl, details) {
    const template = dom.cloneTemplate('#tmpl-lh-snippet__content', tmpl);
    const snippetEl = dom.find('.lh-snippet__snippet-inner', template);

    // First render messages that don't belong to specific lines
    details.generalMessages.forEach(m =>
      snippetEl.append(SnippetRenderer.renderMessage(dom, tmpl, m))
    );
    // Then render the lines and their messages, as well as placeholders where lines are omitted
    snippetEl.append(SnippetRenderer.renderSnippetLines(dom, tmpl, details));

    return template;
  }

  /**
   * @param {DOM} dom
   * @param {DocumentFragment} tmpl
   * @param {LH.Audit.Details.SnippetValue} details
   * @return {DocumentFragment}
   */
  static renderSnippetLines(dom, tmpl, details) {
    const {lineMessages, generalMessages, lineCount, lines} = details;
    const linesWhenCollapsed = getLinesWhenCollapsed(details);
    const hasOnlyGeneralMessages =
      generalMessages.length > 0 && lineMessages.length === 0;

    const lineContainer = dom.createFragment();

    // When a line is not shown in the collapsed state we try to see if we also need an
    // omitted lines placeholder for the expanded state, rather than rendering two separate
    // placeholders.
    let hasPendingOmittedLinesPlaceholderForCollapsedState = false;

    for (let lineNumber = 1; lineNumber <= lineCount; lineNumber++) {
      const {line, previousLine} = getLineAndPreviousLine(lines, lineNumber);
      const {
        line: lineWhenCollapsed,
        previousLine: previousLineWhenCollapsed,
      } = getLineAndPreviousLine(linesWhenCollapsed, lineNumber);

      const showLineWhenCollapsed = !!lineWhenCollapsed;
      const showPreviousLineWhenCollapsed = !!previousLineWhenCollapsed;

      // If we went from showing lines in the collapsed state to not showing them
      // we need to render a placeholder
      if (showPreviousLineWhenCollapsed && !showLineWhenCollapsed) {
        hasPendingOmittedLinesPlaceholderForCollapsedState = true;
      }
      // If we are back to lines being visible in the collapsed and the placeholder
      // hasn't been rendered yet then render it now
      if (
        showLineWhenCollapsed &&
        hasPendingOmittedLinesPlaceholderForCollapsedState
      ) {
        lineContainer.append(
          SnippetRenderer.renderOmittedLinesPlaceholder(
            dom,
            tmpl,
            LineVisibility.WHEN_COLLAPSED
          )
        );
        hasPendingOmittedLinesPlaceholderForCollapsedState = false;
      }

      // Render omitted lines placeholder if we have not already rendered one for this gap
      const isFirstOmittedLineWhenExpanded = !line && !!previousLine;
      const isFirstLineOverallAndIsOmittedWhenExpanded =
        !line && lineNumber === 1;
      if (
        isFirstOmittedLineWhenExpanded ||
        isFirstLineOverallAndIsOmittedWhenExpanded
      ) {
        // In the collapsed state we don't show omitted lines placeholders around
        // the edges of the snippet
        const hasRenderedAllLinesVisibleWhenCollapsed = !linesWhenCollapsed.some(
          l => l.lineNumber > lineNumber
        );
        const onlyShowWhenExpanded =
          hasRenderedAllLinesVisibleWhenCollapsed || lineNumber === 1;
        lineContainer.append(
          SnippetRenderer.renderOmittedLinesPlaceholder(
            dom,
            tmpl,
            onlyShowWhenExpanded
              ? LineVisibility.WHEN_EXPANDED
              : LineVisibility.ALWAYS
          )
        );
        hasPendingOmittedLinesPlaceholderForCollapsedState = false;
      }

      if (!line) {
        // Can't render the line if we don't know its content (instead we've rendered a placeholder)
        continue;
      }

      // Now render the line and any messages
      const messages = getMessagesForLineNumber(lineMessages, lineNumber);
      const highlightLine = messages.length > 0 || hasOnlyGeneralMessages;
      const contentLineDetails = Object.assign({}, line, {
        contentType: highlightLine
          ? LineContentType.CONTENT_HIGHLIGHTED
          : LineContentType.CONTENT_NORMAL,
        visibility: lineWhenCollapsed
          ? LineVisibility.ALWAYS
          : LineVisibility.WHEN_EXPANDED,
      });
      lineContainer.append(
        SnippetRenderer.renderSnippetLine(dom, tmpl, contentLineDetails)
      );

      messages.forEach(message => {
        lineContainer.append(SnippetRenderer.renderMessage(dom, tmpl, message));
      });
    }

    return lineContainer;
  }

  /**
   * @param {DOM} dom
   * @param {ParentNode} templateContext
   * @param {LH.Audit.Details.SnippetValue} details
   * @param {DetailsRenderer} detailsRenderer
   * @return {Element}
   */
  static render(dom, templateContext, details, detailsRenderer) {
    const tmpl = dom.cloneTemplate('#tmpl-lh-snippet', templateContext);
    const snippetEl = dom.find('.lh-snippet', tmpl);

    const header = SnippetRenderer.renderHeader(
      dom,
      tmpl,
      details,
      detailsRenderer,
      () => snippetEl.classList.toggle('lh-snippet--expanded')
    );
    const content = SnippetRenderer.renderSnippetContent(dom, tmpl, details);
    snippetEl.append(header, content);

    return snippetEl;
  }
}

// Allow Node require()'ing.
if (typeof module !== 'undefined' && module.exports) {
  module.exports = SnippetRenderer;
} else {
  self.SnippetRenderer = SnippetRenderer;
}
;
/**
 * @license Copyright 2017 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */
'use strict';

/* global URL */

/**
 * @fileoverview
 * @suppress {reportUnknownTypes}
 */

/**
 * Generate a filenamePrefix of hostname_YYYY-MM-DD_HH-MM-SS
 * Date/time uses the local timezone, however Node has unreliable ICU
 * support, so we must construct a YYYY-MM-DD date format manually. :/
 * @param {{finalUrl: string, fetchTime: string}} lhr
 * @return {string}
 */
function getFilenamePrefix(lhr) {
  const hostname = new URL(lhr.finalUrl).hostname;
  const date = (lhr.fetchTime && new Date(lhr.fetchTime)) || new Date();

  const timeStr = date.toLocaleTimeString('en-US', {hour12: false});
  const dateParts = date.toLocaleDateString('en-US', {
    year: 'numeric', month: '2-digit', day: '2-digit',
  }).split('/');
  // @ts-ignore - parts exists
  dateParts.unshift(dateParts.pop());
  const dateStr = dateParts.join('-');

  const filenamePrefix = `${hostname}_${dateStr}_${timeStr}`;
  // replace characters that are unfriendly to filenames
  return filenamePrefix.replace(/[/?<>\\:*|"]/g, '-');
}

// don't attempt to export in the browser.
if (typeof module !== 'undefined' && module.exports) {
  module.exports = {getFilenamePrefix};
}
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/**
 * Logs messages via a UI butter.
 */
class Logger {
  /**
   * @param {Element} element
   */
  constructor(element) {
    /** @type {Element} */
    this.el = element;
    this._id = undefined;
  }

  /**
   * Shows a butter bar.
   * @param {string} msg The message to show.
   * @param {boolean=} autoHide True to hide the message after a duration.
   *     Default is true.
   */
  log(msg, autoHide = true) {
    this._id && clearTimeout(this._id);

    this.el.textContent = msg;
    this.el.classList.add('show');
    if (autoHide) {
      this._id = setTimeout(_ => {
        this.el.classList.remove('show');
      }, 7000);
    }
  }

  /**
   * @param {string} msg
   */
  warn(msg) {
    this.log('Warning: ' + msg);
  }

  /**
   * @param {string} msg
   */
  error(msg) {
    this.log(msg);

    // Rethrow to make sure it's auditable as an error, but in a setTimeout so page
    // recovers gracefully and user can try loading a report again.
    setTimeout(_ => {
      throw new Error(msg);
    }, 0);
  }

  /**
   * Explicitly hides the butter bar.
   */
  hide() {
    this._id && clearTimeout(this._id);
    this.el.classList.remove('show');
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = Logger;
}
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* eslint-env browser */

/**
 * @fileoverview Adds tools button, print, and other dynamic functionality to
 * the report.
 */

/* globals getFilenamePrefix Util */

/**
 * @param {HTMLTableElement} tableEl
 * @return {Array<HTMLTableRowElement>}
 */
function getTableRows(tableEl) {
  return Array.from(tableEl.tBodies[0].rows);
}

class ReportUIFeatures {
  /**
   * @param {DOM} dom
   */
  constructor(dom) {
    /** @type {LH.Result} */
    this.json; // eslint-disable-line no-unused-expressions
    /** @type {DOM} */
    this._dom = dom;
    /** @type {Document} */
    this._document = this._dom.document();
    /** @type {ParentNode} */
    this._templateContext = this._dom.document();
    /** @type {DropDown} */
    this._dropDown = new DropDown(this._dom);
    /** @type {boolean} */
    this._copyAttempt = false;
    /** @type {HTMLElement} */
    this.topbarEl; // eslint-disable-line no-unused-expressions
    /** @type {HTMLElement} */
    this.scoreScaleEl; // eslint-disable-line no-unused-expressions
    /** @type {HTMLElement} */
    this.stickyHeaderEl; // eslint-disable-line no-unused-expressions
    /** @type {HTMLElement} */
    this.highlightEl; // eslint-disable-line no-unused-expressions

    this.onMediaQueryChange = this.onMediaQueryChange.bind(this);
    this.onCopy = this.onCopy.bind(this);
    this.onDropDownMenuClick = this.onDropDownMenuClick.bind(this);
    this.onKeyUp = this.onKeyUp.bind(this);
    this.collapseAllDetails = this.collapseAllDetails.bind(this);
    this.expandAllDetails = this.expandAllDetails.bind(this);
    this._toggleDarkTheme = this._toggleDarkTheme.bind(this);
    this._updateStickyHeaderOnScroll = this._updateStickyHeaderOnScroll.bind(this);
  }

  /**
   * Adds tools button, print, and other functionality to the report. The method
   * should be called whenever the report needs to be re-rendered.
   * @param {LH.Result} report
   */
  initFeatures(report) {
    this.json = report;

    this._setupMediaQueryListeners();
    this._dropDown.setup(this.onDropDownMenuClick);
    this._setupThirdPartyFilter();
    this._setUpCollapseDetailsAfterPrinting();
    this._resetUIState();
    this._document.addEventListener('keyup', this.onKeyUp);
    this._document.addEventListener('copy', this.onCopy);

    const topbarLogo = this._dom.find('.lh-topbar__logo', this._document);
    topbarLogo.addEventListener('click', () => this._toggleDarkTheme());

    let turnOffTheLights = false;
    // Do not query the system preferences for DevTools - DevTools should only apply dark theme
    // if dark is selected in the settings panel.
    if (!this._dom.isDevTools() && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      turnOffTheLights = true;
    }

    // Fireworks.
    const scoresAll100 = Object.values(report.categories).every(cat => cat.score === 1);
    const hasAllCoreCategories =
      Object.keys(report.categories).filter(id => !Util.isPluginCategory(id)).length >= 5;
    if (scoresAll100 && hasAllCoreCategories) {
      turnOffTheLights = true;
      this._enableFireworks();
    }

    if (turnOffTheLights) {
      this._toggleDarkTheme(true);
    }

    // There is only a sticky header when at least 2 categories are present.
    if (Object.keys(this.json.categories).length >= 2) {
      this._setupStickyHeaderElements();
      const containerEl = this._dom.find('.lh-container', this._document);
      const elToAddScrollListener = this._getScrollParent(containerEl);
      elToAddScrollListener.addEventListener('scroll', this._updateStickyHeaderOnScroll);

      // Use ResizeObserver where available.
      // TODO: there is an issue with incorrect position numbers and, as a result, performance
      // issues due to layout thrashing.
      // See https://github.com/GoogleChrome/lighthouse/pull/9023/files#r288822287 for details.
      // For now, limit to DevTools.
      if (this._dom.isDevTools()) {
        const resizeObserver = new window.ResizeObserver(this._updateStickyHeaderOnScroll);
        resizeObserver.observe(containerEl);
      } else {
        window.addEventListener('resize', this._updateStickyHeaderOnScroll);
      }
    }

    // Show the metric descriptions by default when there is an error.
    const hasMetricError = report.categories.performance && report.categories.performance.auditRefs
      .some(audit => Boolean(audit.group === 'metrics' && report.audits[audit.id].errorMessage));
    if (hasMetricError) {
      const toggleInputEl = /** @type {HTMLInputElement} */ (
        this._dom.find('.lh-metrics-toggle__input', this._document));
      toggleInputEl.checked = true;
    }
  }

  /**
   * Define a custom element for <templates> to be extracted from. For example:
   *     this.setTemplateContext(new DOMParser().parseFromString(htmlStr, 'text/html'))
   * @param {ParentNode} context
   */
  setTemplateContext(context) {
    this._templateContext = context;
  }

  /**
   * Finds the first scrollable ancestor of `element`. Falls back to the document.
   * @param {HTMLElement} element
   * @return {Node}
   */
  _getScrollParent(element) {
    const {overflowY} = window.getComputedStyle(element);
    const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden';

    if (isScrollable) {
      return element;
    }

    if (element.parentElement) {
      return this._getScrollParent(element.parentElement);
    }

    return document;
  }

  _enableFireworks() {
    const scoresContainer = this._dom.find('.lh-scores-container', this._document);
    scoresContainer.classList.add('score100');
    scoresContainer.addEventListener('click', _ => {
      scoresContainer.classList.toggle('fireworks-paused');
    });
  }

  /**
   * Fires a custom DOM event on target.
   * @param {string} name Name of the event.
   * @param {Node=} target DOM node to fire the event on.
   * @param {*=} detail Custom data to include.
   */
  _fireEventOn(name, target = this._document, detail) {
    const event = new CustomEvent(name, detail ? {detail} : undefined);
    target.dispatchEvent(event);
  }

  _setupMediaQueryListeners() {
    const mediaQuery = self.matchMedia('(max-width: 500px)');
    mediaQuery.addListener(this.onMediaQueryChange);
    // Ensure the handler is called on init
    this.onMediaQueryChange(mediaQuery);
  }

  /**
   * Handle media query change events.
   * @param {MediaQueryList|MediaQueryListEvent} mql
   */
  onMediaQueryChange(mql) {
    const root = this._dom.find('.lh-root', this._document);
    root.classList.toggle('lh-narrow', mql.matches);
  }

  _setupThirdPartyFilter() {
    // Some audits should not display the third party filter option.
    const thirdPartyFilterAuditExclusions = [
      // This audit deals explicitly with third party resources.
      'uses-rel-preconnect',
    ];

    // Get all tables with a text url column.
    /** @type {Array<HTMLTableElement>} */
    const tables = Array.from(this._document.querySelectorAll('.lh-table'));
    const tablesWithUrls = tables
      .filter(el => el.querySelector('td.lh-table-column--url'))
      .filter(el => {
        const containingAudit = el.closest('.lh-audit');
        if (!containingAudit) throw new Error('.lh-table not within audit');
        return !thirdPartyFilterAuditExclusions.includes(containingAudit.id);
      });

    tablesWithUrls.forEach((tableEl, index) => {
      const urlItems = this._getUrlItems(tableEl);
      const thirdPartyRows = this._getThirdPartyRows(tableEl, urlItems, this.json.finalUrl);

      // create input box
      const filterTemplate = this._dom.cloneTemplate('#tmpl-lh-3p-filter', this._templateContext);
      const filterInput =
        /** @type {HTMLInputElement} */ (this._dom.find('input', filterTemplate));
      const id = `lh-3p-filter-label--${index}`;

      filterInput.id = id;
      filterInput.addEventListener('change', e => {
        // Remove rows from the dom and keep track of them to re-add on uncheck.
        // Why removing instead of hiding? To keep nth-child(even) background-colors working.
        if (e.target instanceof HTMLInputElement && !e.target.checked) {
          for (const row of thirdPartyRows.values()) {
            row.remove();
          }
        } else {
          // Add row elements back to original positions.
          for (const [position, row] of thirdPartyRows.entries()) {
            const childrenArr = getTableRows(tableEl);
            tableEl.tBodies[0].insertBefore(row, childrenArr[position]);
          }
        }
      });

      this._dom.find('label', filterTemplate).setAttribute('for', id);
      this._dom.find('.lh-3p-filter-count', filterTemplate).textContent =
          `${thirdPartyRows.size}`;
      this._dom.find('.lh-3p-ui-string', filterTemplate).textContent =
          Util.UIStrings.thirdPartyResourcesLabel;

      // If all or none of the rows are 3rd party, disable the checkbox.
      if (thirdPartyRows.size === urlItems.length || !thirdPartyRows.size) {
        filterInput.disabled = true;
        filterInput.checked = thirdPartyRows.size === urlItems.length;
      }

      // Finally, add checkbox to the DOM.
      if (!tableEl.parentNode) return; // Keep tsc happy.
      tableEl.parentNode.insertBefore(filterTemplate, tableEl);
    });
  }

  /**
   * From a table with URL entries, finds the rows containing third-party URLs
   * and returns a Map of those rows, mapping from row index to row Element.
   * @param {HTMLTableElement} el
   * @param {string} finalUrl
   * @param {Array<HTMLElement>} urlItems
   * @return {Map<number, HTMLTableRowElement>}
   */
  _getThirdPartyRows(el, urlItems, finalUrl) {
    const finalUrlRootDomain = Util.getRootDomain(finalUrl);

    /** @type {Map<number, HTMLTableRowElement>} */
    const thirdPartyRows = new Map();
    for (const urlItem of urlItems) {
      const datasetUrl = urlItem.dataset.url;
      if (!datasetUrl) continue;
      const isThirdParty = Util.getRootDomain(datasetUrl) !== finalUrlRootDomain;
      if (!isThirdParty) continue;

      const urlRowEl = urlItem.closest('tr');
      if (urlRowEl) {
        const rowPosition = getTableRows(el).indexOf(urlRowEl);
        thirdPartyRows.set(rowPosition, urlRowEl);
      }
    }

    return thirdPartyRows;
  }

  /**
   * From a table, finds and returns URL items.
   * @param {HTMLTableElement} tableEl
   * @return {Array<HTMLElement>}
   */
  _getUrlItems(tableEl) {
    return this._dom.findAll('.lh-text__url', tableEl);
  }

  _setupStickyHeaderElements() {
    this.topbarEl = this._dom.find('.lh-topbar', this._document);
    this.scoreScaleEl = this._dom.find('.lh-scorescale', this._document);
    this.stickyHeaderEl = this._dom.find('.lh-sticky-header', this._document);

    // Highlighter will be absolutely positioned at first gauge, then transformed on scroll.
    this.highlightEl = this._dom.createChildOf(this.stickyHeaderEl, 'div', 'lh-highlighter');
  }

  /**
   * Handle copy events.
   * @param {ClipboardEvent} e
   */
  onCopy(e) {
    // Only handle copy button presses (e.g. ignore the user copying page text).
    if (this._copyAttempt && e.clipboardData) {
      // We want to write our own data to the clipboard, not the user's text selection.
      e.preventDefault();
      e.clipboardData.setData('text/plain', JSON.stringify(this.json, null, 2));

      this._fireEventOn('lh-log', this._document, {
        cmd: 'log', msg: 'Report JSON copied to clipboard',
      });
    }

    this._copyAttempt = false;
  }

  /**
   * Copies the report JSON to the clipboard (if supported by the browser).
   */
  onCopyButtonClick() {
    this._fireEventOn('lh-analytics', this._document, {
      cmd: 'send',
      fields: {hitType: 'event', eventCategory: 'report', eventAction: 'copy'},
    });

    try {
      if (this._document.queryCommandSupported('copy')) {
        this._copyAttempt = true;

        // Note: In Safari 10.0.1, execCommand('copy') returns true if there's
        // a valid text selection on the page. See http://caniuse.com/#feat=clipboard.
        if (!this._document.execCommand('copy')) {
          this._copyAttempt = false; // Prevent event handler from seeing this as a copy attempt.

          this._fireEventOn('lh-log', this._document, {
            cmd: 'warn', msg: 'Your browser does not support copy to clipboard.',
          });
        }
      }
    } catch (/** @type {Error} */ e) {
      this._copyAttempt = false;
      this._fireEventOn('lh-log', this._document, {cmd: 'log', msg: e.message});
    }
  }

  /**
   * Resets the state of page before capturing the page for export.
   * When the user opens the exported HTML page, certain UI elements should
   * be in their closed state (not opened) and the templates should be unstamped.
   */
  _resetUIState() {
    this._dropDown.close();
    this._dom.resetTemplates();
  }

  /**
   * Handler for tool button.
   * @param {Event} e
   */
  onDropDownMenuClick(e) {
    e.preventDefault();

    const el = /** @type {?Element} */ (e.target);

    if (!el || !el.hasAttribute('data-action')) {
      return;
    }

    switch (el.getAttribute('data-action')) {
      case 'copy':
        this.onCopyButtonClick();
        break;
      case 'print-summary':
        this.collapseAllDetails();
        this._print();
        break;
      case 'print-expanded':
        this.expandAllDetails();
        this._print();
        break;
      case 'save-json': {
        const jsonStr = JSON.stringify(this.json, null, 2);
        this._saveFile(new Blob([jsonStr], {type: 'application/json'}));
        break;
      }
      case 'save-html': {
        const htmlStr = this.getReportHtml();
        try {
          this._saveFile(new Blob([htmlStr], {type: 'text/html'}));
        } catch (/** @type {Error} */ e) {
          this._fireEventOn('lh-log', this._document, {
            cmd: 'error', msg: 'Could not export as HTML. ' + e.message,
          });
        }
        break;
      }
      case 'open-viewer': {
        const viewerPath = '/lighthouse/viewer/';
        ReportUIFeatures.openTabAndSendJsonReport(this.json, viewerPath);
        break;
      }
      case 'save-gist': {
        this.saveAsGist();
        break;
      }
      case 'toggle-dark': {
        this._toggleDarkTheme();
        break;
      }
    }

    this._dropDown.close();
  }

  _print() {
    self.print();
  }

  /**
   * Keyup handler for the document.
   * @param {KeyboardEvent} e
   */
  onKeyUp(e) {
    // Ctrl+P - Expands audit details when user prints via keyboard shortcut.
    if ((e.ctrlKey || e.metaKey) && e.keyCode === 80) {
      this._dropDown.close();
    }
  }

  /**
   * Opens a new tab to the online viewer and sends the local page's JSON results
   * to the online viewer using postMessage.
   * @param {LH.Result} reportJson
   * @param {string} viewerPath
   * @protected
   */
  static openTabAndSendJsonReport(reportJson, viewerPath) {
    const VIEWER_ORIGIN = 'https://googlechrome.github.io';
    // Chrome doesn't allow us to immediately postMessage to a popup right
    // after it's created. Normally, we could also listen for the popup window's
    // load event, however it is cross-domain and won't fire. Instead, listen
    // for a message from the target app saying "I'm open".
    const json = reportJson;
    window.addEventListener('message', function msgHandler(messageEvent) {
      if (messageEvent.origin !== VIEWER_ORIGIN) {
        return;
      }
      if (popup && messageEvent.data.opened) {
        popup.postMessage({lhresults: json}, VIEWER_ORIGIN);
        window.removeEventListener('message', msgHandler);
      }
    });

    // The popup's window.name is keyed by version+url+fetchTime, so we reuse/select tabs correctly
    // @ts-ignore - If this is a v2 LHR, use old `generatedTime`.
    const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
    const fetchTime = json.fetchTime || fallbackFetchTime;
    const windowName = `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
    const popup = window.open(`${VIEWER_ORIGIN}${viewerPath}`, windowName);
  }

  /**
   * Expands all audit `<details>`.
   * Ideally, a print stylesheet could take care of this, but CSS has no way to
   * open a `<details>` element.
   */
  expandAllDetails() {
    const details = /** @type {Array<HTMLDetailsElement>} */ (this._dom.findAll(
        '.lh-categories details', this._document));
    details.map(detail => detail.open = true);
  }

  /**
   * Collapses all audit `<details>`.
   * open a `<details>` element.
   */
  collapseAllDetails() {
    const details = /** @type {Array<HTMLDetailsElement>} */ (this._dom.findAll(
        '.lh-categories details', this._document));
    details.map(detail => detail.open = false);
  }

  /**
   * Sets up listeners to collapse audit `<details>` when the user closes the
   * print dialog, all `<details>` are collapsed.
   */
  _setUpCollapseDetailsAfterPrinting() {
    // FF and IE implement these old events.
    if ('onbeforeprint' in self) {
      self.addEventListener('afterprint', this.collapseAllDetails);
    } else {
      const win = /** @type {Window} */ (self);
      // Note: FF implements both window.onbeforeprint and media listeners. However,
      // it doesn't matchMedia doesn't fire when matching 'print'.
      win.matchMedia('print').addListener(mql => {
        if (mql.matches) {
          this.expandAllDetails();
        } else {
          this.collapseAllDetails();
        }
      });
    }
  }

  /**
   * Returns the html that recreates this report.
   * @return {string}
   * @protected
   */
  getReportHtml() {
    this._resetUIState();
    return this._document.documentElement.outerHTML;
  }

  /**
   * Save json as a gist. Unimplemented in base UI features.
   * @protected
   */
  saveAsGist() {
    throw new Error('Cannot save as gist from base report');
  }

  /**
   * Downloads a file (blob) using a[download].
   * @param {Blob|File} blob The file to save.
   * @private
   */
  _saveFile(blob) {
    const filename = getFilenamePrefix({
      finalUrl: this.json.finalUrl,
      fetchTime: this.json.fetchTime,
    });

    const ext = blob.type.match('json') ? '.json' : '.html';
    const href = URL.createObjectURL(blob);

    const a = this._dom.createElement('a');
    a.download = `${filename}${ext}`;
    a.href = href;
    this._document.body.appendChild(a); // Firefox requires anchor to be in the DOM.
    a.click();

    // cleanup.
    this._document.body.removeChild(a);
    setTimeout(_ => URL.revokeObjectURL(href), 500);
  }

  /**
   * @private
   * @param {boolean} [force]
   */
  _toggleDarkTheme(force) {
    const el = this._dom.find('.lh-vars', this._document);
    // This seems unnecessary, but in DevTools, passing "undefined" as the second
    // parameter acts like passing "false".
    // https://github.com/ChromeDevTools/devtools-frontend/blob/dd6a6d4153647c2a4203c327c595692c5e0a4256/front_end/dom_extension/DOMExtension.js#L809-L819
    if (typeof force === 'undefined') {
      el.classList.toggle('dark');
    } else {
      el.classList.toggle('dark', force);
    }
  }

  _updateStickyHeaderOnScroll() {
    // Show sticky header when the score scale begins to go underneath the topbar.
    const topbarBottom = this.topbarEl.getBoundingClientRect().bottom;
    const scoreScaleTop = this.scoreScaleEl.getBoundingClientRect().top;
    const showStickyHeader = topbarBottom >= scoreScaleTop;

    // Highlight mini gauge when section is in view.
    // In view = the last category that starts above the middle of the window.
    const categoryEls = Array.from(this._document.querySelectorAll('.lh-category'));
    const categoriesAboveTheMiddle =
      categoryEls.filter(el => el.getBoundingClientRect().top - window.innerHeight / 2 < 0);
    const highlightIndex =
      categoriesAboveTheMiddle.length > 0 ? categoriesAboveTheMiddle.length - 1 : 0;

    // Category order matches gauge order in sticky header.
    const gaugeWrapperEls = this.stickyHeaderEl.querySelectorAll('.lh-gauge__wrapper');
    const gaugeToHighlight = gaugeWrapperEls[highlightIndex];
    const origin = gaugeWrapperEls[0].getBoundingClientRect().left;
    const offset = gaugeToHighlight.getBoundingClientRect().left - origin;

    // Mutate at end to avoid layout thrashing.
    this.highlightEl.style.transform = `translate(${offset}px)`;
    this.stickyHeaderEl.classList.toggle('lh-sticky-header--visible', showStickyHeader);
  }
}

class DropDown {
  /**
   * @param {DOM} dom
   */
  constructor(dom) {
    /** @type {DOM} */
    this._dom = dom;
    /** @type {HTMLElement} */
    this._toggleEl; // eslint-disable-line no-unused-expressions
    /** @type {HTMLElement} */
    this._menuEl; // eslint-disable-line no-unused-expressions

    this.onDocumentKeyDown = this.onDocumentKeyDown.bind(this);
    this.onToggleClick = this.onToggleClick.bind(this);
    this.onToggleKeydown = this.onToggleKeydown.bind(this);
    this.onMenuKeydown = this.onMenuKeydown.bind(this);

    this._getNextMenuItem = this._getNextMenuItem.bind(this);
    this._getNextSelectableNode = this._getNextSelectableNode.bind(this);
    this._getPreviousMenuItem = this._getPreviousMenuItem.bind(this);
  }

  /**
   * @param {function(MouseEvent): any} menuClickHandler
   */
  setup(menuClickHandler) {
    this._toggleEl = this._dom.find('.lh-tools__button', this._dom.document());
    this._toggleEl.addEventListener('click', this.onToggleClick);
    this._toggleEl.addEventListener('keydown', this.onToggleKeydown);

    this._menuEl = this._dom.find('.lh-tools__dropdown', this._dom.document());
    this._menuEl.addEventListener('keydown', this.onMenuKeydown);
    this._menuEl.addEventListener('click', menuClickHandler);
  }

  close() {
    this._toggleEl.classList.remove('active');
    this._toggleEl.setAttribute('aria-expanded', 'false');
    if (this._menuEl.contains(this._dom.document().activeElement)) {
      // Refocus on the tools button if the drop down last had focus
      this._toggleEl.focus();
    }
    this._dom.document().removeEventListener('keydown', this.onDocumentKeyDown);
  }

  /**
   * @param {HTMLElement} firstFocusElement
   */
  open(firstFocusElement) {
    if (this._toggleEl.classList.contains('active')) {
      // If the drop down is already open focus on the element
      firstFocusElement.focus();
    } else {
      // Wait for drop down transition to complete so options are focusable.
      this._menuEl.addEventListener('transitionend', () => {
        firstFocusElement.focus();
      }, {once: true});
    }

    this._toggleEl.classList.add('active');
    this._toggleEl.setAttribute('aria-expanded', 'true');
    this._dom.document().addEventListener('keydown', this.onDocumentKeyDown);
  }

  /**
   * Click handler for tools button.
   * @param {Event} e
   */
  onToggleClick(e) {
    e.preventDefault();
    e.stopImmediatePropagation();

    if (this._toggleEl.classList.contains('active')) {
      this.close();
    } else {
      this.open(this._getNextMenuItem());
    }
  }

  /**
   * Handler for tool button.
   * @param {KeyboardEvent} e
   */
  onToggleKeydown(e) {
    switch (e.code) {
      case 'ArrowUp':
        e.preventDefault();
        this.open(this._getPreviousMenuItem());
        break;
      case 'ArrowDown':
      case 'Enter':
      case ' ':
        e.preventDefault();
        this.open(this._getNextMenuItem());
        break;
      default:
       // no op
    }
  }

  /**
   * Handler for tool DropDown.
   * @param {KeyboardEvent} e
   */
  onMenuKeydown(e) {
    const el = /** @type {?HTMLElement} */ (e.target);

    switch (e.code) {
      case 'ArrowUp':
        e.preventDefault();
        this._getPreviousMenuItem(el).focus();
        break;
      case 'ArrowDown':
        e.preventDefault();
        this._getNextMenuItem(el).focus();
        break;
      case 'Home':
        e.preventDefault();
        this._getNextMenuItem().focus();
        break;
      case 'End':
        e.preventDefault();
        this._getPreviousMenuItem().focus();
        break;
      default:
       // no op
    }
  }

  /**
   * Keydown handler for the document.
   * @param {KeyboardEvent} e
   */
  onDocumentKeyDown(e) {
    if (e.keyCode === 27) { // ESC
      this.close();
    }
  }

  /**
   * @param {Array<Node>} allNodes
   * @param {?Node=} startNode
   * @returns {Node}
   */
  _getNextSelectableNode(allNodes, startNode) {
    const nodes = allNodes.filter((node) => {
      if (!(node instanceof HTMLElement)) {
        return false;
      }

      // 'Save as Gist' option may be disabled.
      if (node.hasAttribute('disabled')) {
        return false;
      }

      // 'Save as Gist' option may have display none.
      if (window.getComputedStyle(node).display === 'none') {
        return false;
      }

      return true;
    });

    let nextIndex = startNode ? (nodes.indexOf(startNode) + 1) : 0;
    if (nextIndex >= nodes.length) {
      nextIndex = 0;
    }

    return nodes[nextIndex];
  }

  /**
   * @param {?Element=} startEl
   * @returns {HTMLElement}
   */
  _getNextMenuItem(startEl) {
    const nodes = Array.from(this._menuEl.childNodes);
    return /** @type {HTMLElement} */ (this._getNextSelectableNode(nodes, startEl));
  }

  /**
   * @param {?Element=} startEl
   * @returns {HTMLElement}
   */
  _getPreviousMenuItem(startEl) {
    const nodes = Array.from(this._menuEl.childNodes).reverse();
    return /** @type {HTMLElement} */ (this._getNextSelectableNode(nodes, startEl));
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = ReportUIFeatures;
} else {
  self.ReportUIFeatures = ReportUIFeatures;
}
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* globals self, Util */

/** @typedef {import('./dom.js')} DOM */
/** @typedef {import('./report-renderer.js')} ReportRenderer */
/** @typedef {import('./details-renderer.js')} DetailsRenderer */
/** @typedef {import('./util.js')} Util */
/** @typedef {'failed'|'warning'|'manual'|'passed'|'notApplicable'} TopLevelClumpId */

class CategoryRenderer {
  /**
   * @param {DOM} dom
   * @param {DetailsRenderer} detailsRenderer
   */
  constructor(dom, detailsRenderer) {
    /** @type {DOM} */
    this.dom = dom;
    /** @type {DetailsRenderer} */
    this.detailsRenderer = detailsRenderer;
    /** @type {ParentNode} */
    this.templateContext = this.dom.document();

    this.detailsRenderer.setTemplateContext(this.templateContext);
  }

  /**
   * Display info per top-level clump. Define on class to avoid race with Util init.
   */
  get _clumpTitles() {
    return {
      warning: Util.UIStrings.warningAuditsGroupTitle,
      manual: Util.UIStrings.manualAuditsGroupTitle,
      passed: Util.UIStrings.passedAuditsGroupTitle,
      notApplicable: Util.UIStrings.notApplicableAuditsGroupTitle,
    };
  }

  /**
   * @param {LH.ReportResult.AuditRef} audit
   * @return {Element}
   */
  renderAudit(audit) {
    const tmpl = this.dom.cloneTemplate('#tmpl-lh-audit', this.templateContext);
    return this.populateAuditValues(audit, tmpl);
  }

  /**
   * Populate an DOM tree with audit details. Used by renderAudit and renderOpportunity
   * @param {LH.ReportResult.AuditRef} audit
   * @param {DocumentFragment} tmpl
   * @return {Element}
   */
  populateAuditValues(audit, tmpl) {
    const auditEl = this.dom.find('.lh-audit', tmpl);
    auditEl.id = audit.result.id;
    const scoreDisplayMode = audit.result.scoreDisplayMode;

    if (audit.result.displayValue) {
      this.dom.find('.lh-audit__display-text', auditEl).textContent = audit.result.displayValue;
    }

    const titleEl = this.dom.find('.lh-audit__title', auditEl);
    titleEl.appendChild(this.dom.convertMarkdownCodeSnippets(audit.result.title));
    this.dom.find('.lh-audit__description', auditEl)
        .appendChild(this.dom.convertMarkdownLinkSnippets(audit.result.description));

    if (audit.stackPacks) {
      audit.stackPacks.forEach(pack => {
        const packElm = this.dom.createElement('div');
        packElm.classList.add('lh-audit__stackpack');

        const packElmImg = this.dom.createElement('img');
        packElmImg.classList.add('lh-audit__stackpack__img');
        packElmImg.src = pack.iconDataURL;
        packElmImg.alt = pack.title;
        packElm.appendChild(packElmImg);

        packElm.appendChild(this.dom.convertMarkdownLinkSnippets(pack.description));

        this.dom.find('.lh-audit__stackpacks', auditEl)
          .appendChild(packElm);
      });
    }

    const header = /** @type {HTMLDetailsElement} */ (this.dom.find('details', auditEl));
    if (audit.result.details) {
      const elem = this.detailsRenderer.render(audit.result.details);
      if (elem) {
        elem.classList.add('lh-details');
        header.appendChild(elem);
      }
    }

    // Add chevron SVG to the end of the summary
    this.dom.find('.lh-chevron-container', auditEl).appendChild(this._createChevron());
    this._setRatingClass(auditEl, audit.result.score, scoreDisplayMode);

    if (audit.result.scoreDisplayMode === 'error') {
      auditEl.classList.add(`lh-audit--error`);
      const textEl = this.dom.find('.lh-audit__display-text', auditEl);
      textEl.textContent = Util.UIStrings.errorLabel;
      textEl.classList.add('tooltip-boundary');
      const tooltip = this.dom.createChildOf(textEl, 'div', 'tooltip tooltip--error');
      tooltip.textContent = audit.result.errorMessage || Util.UIStrings.errorMissingAuditInfo;
    } else if (audit.result.explanation) {
      const explEl = this.dom.createChildOf(titleEl, 'div', 'lh-audit-explanation');
      explEl.textContent = audit.result.explanation;
    }
    const warnings = audit.result.warnings;
    if (!warnings || warnings.length === 0) return auditEl;

    // Add list of warnings or singular warning
    const warningsEl = this.dom.createChildOf(titleEl, 'div', 'lh-warnings');
    this.dom.createChildOf(warningsEl, 'span').textContent = Util.UIStrings.warningHeader;
    if (warnings.length === 1) {
      warningsEl.appendChild(this.dom.document().createTextNode(warnings.join('')));
    } else {
      const warningsUl = this.dom.createChildOf(warningsEl, 'ul');
      for (const warning of warnings) {
        const item = this.dom.createChildOf(warningsUl, 'li');
        item.textContent = warning;
      }
    }
    return auditEl;
  }

  /**
   * @return {HTMLElement}
   */
  _createChevron() {
    const chevronTmpl = this.dom.cloneTemplate('#tmpl-lh-chevron', this.templateContext);
    const chevronEl = this.dom.find('.lh-chevron', chevronTmpl);
    return chevronEl;
  }

  /**
   * @param {Element} element DOM node to populate with values.
   * @param {number|null} score
   * @param {string} scoreDisplayMode
   * @return {Element}
   */
  _setRatingClass(element, score, scoreDisplayMode) {
    const rating = Util.calculateRating(score, scoreDisplayMode);
    element.classList.add(`lh-audit--${scoreDisplayMode.toLowerCase()}`);
    if (scoreDisplayMode !== 'informative') {
      element.classList.add(`lh-audit--${rating}`);
    }
    return element;
  }

  /**
   * @param {LH.ReportResult.Category} category
   * @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {Element}
   */
  renderCategoryHeader(category, groupDefinitions) {
    const tmpl = this.dom.cloneTemplate('#tmpl-lh-category-header', this.templateContext);

    const gaugeContainerEl = this.dom.find('.lh-score__gauge', tmpl);
    const gaugeEl = this.renderScoreGauge(category, groupDefinitions);
    gaugeContainerEl.appendChild(gaugeEl);

    if (category.description) {
      const descEl = this.dom.convertMarkdownLinkSnippets(category.description);
      this.dom.find('.lh-category-header__description', tmpl).appendChild(descEl);
    }

    return /** @type {Element} */ (tmpl.firstElementChild);
  }

  /**
   * Renders the group container for a group of audits. Individual audit elements can be added
   * directly to the returned element.
   * @param {LH.Result.ReportGroup} group
   * @return {Element}
   */
  renderAuditGroup(group) {
    const groupEl = this.dom.createElement('div', 'lh-audit-group');

    const auditGroupHeader = this.dom.createElement('div', 'lh-audit-group__header');

    this.dom.createChildOf(auditGroupHeader, 'span', 'lh-audit-group__title')
      .textContent = group.title;
    if (group.description) {
      const descriptionEl = this.dom.convertMarkdownLinkSnippets(group.description);
      descriptionEl.classList.add('lh-audit-group__description');
      auditGroupHeader.appendChild(descriptionEl);
    }
    groupEl.appendChild(auditGroupHeader);

    return groupEl;
  }

  /**
   * Takes an array of auditRefs, groups them if requested, then returns an
   * array of audit and audit-group elements.
   * @param {Array<LH.ReportResult.AuditRef>} auditRefs
   * @param {Object<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {Array<Element>}
   */
  _renderGroupedAudits(auditRefs, groupDefinitions) {
    // Audits grouped by their group (or under notAGroup).
    /** @type {Map<string, Array<LH.ReportResult.AuditRef>>} */
    const grouped = new Map();

    // Add audits without a group first so they will appear first.
    const notAGroup = 'NotAGroup';
    grouped.set(notAGroup, []);

    for (const auditRef of auditRefs) {
      const groupId = auditRef.group || notAGroup;
      const groupAuditRefs = grouped.get(groupId) || [];
      groupAuditRefs.push(auditRef);
      grouped.set(groupId, groupAuditRefs);
    }

    /** @type {Array<Element>} */
    const auditElements = [];

    for (const [groupId, groupAuditRefs] of grouped) {
      if (groupId === notAGroup) {
        // Push not-grouped audits individually.
        for (const auditRef of groupAuditRefs) {
          auditElements.push(this.renderAudit(auditRef));
        }
        continue;
      }

      // Push grouped audits as a group.
      const groupDef = groupDefinitions[groupId];
      const auditGroupElem = this.renderAuditGroup(groupDef);
      for (const auditRef of groupAuditRefs) {
        auditGroupElem.appendChild(this.renderAudit(auditRef));
      }
      auditGroupElem.classList.add(`lh-audit-group--${groupId}`);
      auditElements.push(auditGroupElem);
    }

    return auditElements;
  }

  /**
   * Take a set of audits, group them if they have groups, then render in a top-level
   * clump that can't be expanded/collapsed.
   * @param {Array<LH.ReportResult.AuditRef>} auditRefs
   * @param {Object<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {Element}
   */
  renderUnexpandableClump(auditRefs, groupDefinitions) {
    const clumpElement = this.dom.createElement('div');
    const elements = this._renderGroupedAudits(auditRefs, groupDefinitions);
    elements.forEach(elem => clumpElement.appendChild(elem));
    return clumpElement;
  }

  /**
   * Take a set of audits and render in a top-level, expandable clump that starts
   * in a collapsed state.
   * @param {Exclude<TopLevelClumpId, 'failed'>} clumpId
   * @param {{auditRefs: Array<LH.ReportResult.AuditRef>, description?: string}} clumpOpts
   * @return {Element}
   */
  renderClump(clumpId, {auditRefs, description}) {
    const clumpTmpl = this.dom.cloneTemplate('#tmpl-lh-clump', this.templateContext);
    const clumpElement = this.dom.find('.lh-clump', clumpTmpl);

    if (clumpId === 'warning') {
      clumpElement.setAttribute('open', '');
    }

    const summaryInnerEl = this.dom.find('.lh-audit-group__summary', clumpElement);
    const chevronEl = summaryInnerEl.appendChild(this._createChevron());
    chevronEl.title = Util.UIStrings.auditGroupExpandTooltip;

    const headerEl = this.dom.find('.lh-audit-group__header', clumpElement);
    const title = this._clumpTitles[clumpId];
    this.dom.find('.lh-audit-group__title', headerEl).textContent = title;
    if (description) {
      const descriptionEl = this.dom.convertMarkdownLinkSnippets(description);
      descriptionEl.classList.add('lh-audit-group__description');
      headerEl.appendChild(descriptionEl);
    }

    const itemCountEl = this.dom.find('.lh-audit-group__itemcount', clumpElement);
    itemCountEl.textContent = `(${auditRefs.length})`;

    // Add all audit results to the clump.
    const auditElements = auditRefs.map(this.renderAudit.bind(this));
    clumpElement.append(...auditElements);

    clumpElement.classList.add(`lh-clump--${clumpId.toLowerCase()}`);
    return clumpElement;
  }

  /**
   * @param {ParentNode} context
   */
  setTemplateContext(context) {
    this.templateContext = context;
    this.detailsRenderer.setTemplateContext(context);
  }

  /**
   * @param {LH.ReportResult.Category} category
   * @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {DocumentFragment}
   */
  renderScoreGauge(category, groupDefinitions) { // eslint-disable-line no-unused-vars
    const tmpl = this.dom.cloneTemplate('#tmpl-lh-gauge', this.templateContext);
    const wrapper = /** @type {HTMLAnchorElement} */ (this.dom.find('.lh-gauge__wrapper', tmpl));
    wrapper.href = `#${category.id}`;
    wrapper.classList.add(`lh-gauge__wrapper--${Util.calculateRating(category.score)}`);

    if (Util.isPluginCategory(category.id)) {
      wrapper.classList.add('lh-gauge__wrapper--plugin');
    }

    // Cast `null` to 0
    const numericScore = Number(category.score);
    const gauge = this.dom.find('.lh-gauge', tmpl);
    // 352 is ~= 2 * Math.PI * gauge radius (56)
    // https://codepen.io/xgad/post/svg-radial-progress-meters
    // score of 50: `stroke-dasharray: 176 352`;
    /** @type {?SVGCircleElement} */
    const gaugeArc = gauge.querySelector('.lh-gauge-arc');
    if (gaugeArc) {
      gaugeArc.style.strokeDasharray = `${numericScore * 352} 352`;
    }

    const scoreOutOf100 = Math.round(numericScore * 100);
    const percentageEl = this.dom.find('.lh-gauge__percentage', tmpl);
    percentageEl.textContent = scoreOutOf100.toString();
    if (category.score === null) {
      percentageEl.textContent = '?';
      percentageEl.title = Util.UIStrings.errorLabel;
    }

    this.dom.find('.lh-gauge__label', tmpl).textContent = category.title;
    return tmpl;
  }

  /**
   * @param {LH.ReportResult.AuditRef} audit
   * @return {boolean}
   */
  _auditHasWarning(audit) {
    return Boolean(audit.result.warnings && audit.result.warnings.length);
  }

  /**
   * Returns the id of the top-level clump to put this audit in.
   * @param {LH.ReportResult.AuditRef} auditRef
   * @return {TopLevelClumpId}
   */
  _getClumpIdForAuditRef(auditRef) {
    const scoreDisplayMode = auditRef.result.scoreDisplayMode;
    if (scoreDisplayMode === 'manual' || scoreDisplayMode === 'notApplicable') {
      return scoreDisplayMode;
    }

    if (Util.showAsPassed(auditRef.result)) {
      if (this._auditHasWarning(auditRef)) {
        return 'warning';
      } else {
        return 'passed';
      }
    } else {
      return 'failed';
    }
  }

  /**
   * Renders a set of top level sections (clumps), under a status of failed, warning,
   * manual, passed, or notApplicable. The result ends up something like:
   *
   * failed clump
   *   ├── audit 1 (w/o group)
   *   ├── audit 2 (w/o group)
   *   ├── audit group
   *   |  ├── audit 3
   *   |  └── audit 4
   *   └── audit group
   *      ├── audit 5
   *      └── audit 6
   * other clump (e.g. 'manual')
   *   ├── audit 1
   *   ├── audit 2
   *   ├── …
   *   ⋮
   * @param {LH.ReportResult.Category} category
   * @param {Object<string, LH.Result.ReportGroup>} [groupDefinitions]
   * @return {Element}
   */
  render(category, groupDefinitions = {}) {
    const element = this.dom.createElement('div', 'lh-category');
    this.createPermalinkSpan(element, category.id);
    element.appendChild(this.renderCategoryHeader(category, groupDefinitions));

    // Top level clumps for audits, in order they will appear in the report.
    /** @type {Map<TopLevelClumpId, Array<LH.ReportResult.AuditRef>>} */
    const clumps = new Map();
    clumps.set('failed', []);
    clumps.set('warning', []);
    clumps.set('manual', []);
    clumps.set('passed', []);
    clumps.set('notApplicable', []);

    // Sort audits into clumps.
    for (const auditRef of category.auditRefs) {
      const clumpId = this._getClumpIdForAuditRef(auditRef);
      const clump = /** @type {Array<LH.ReportResult.AuditRef>} */ (clumps.get(clumpId)); // already defined
      clump.push(auditRef);
      clumps.set(clumpId, clump);
    }

    // Render each clump.
    for (const [clumpId, auditRefs] of clumps) {
      if (auditRefs.length === 0) continue;

      if (clumpId === 'failed') {
        const clumpElem = this.renderUnexpandableClump(auditRefs, groupDefinitions);
        clumpElem.classList.add(`lh-clump--failed`);
        element.appendChild(clumpElem);
        continue;
      }

      const description = clumpId === 'manual' ? category.manualDescription : undefined;
      const clumpElem = this.renderClump(clumpId, {auditRefs, description});
      element.appendChild(clumpElem);
    }

    return element;
  }

  /**
   * Create a non-semantic span used for hash navigation of categories
   * @param {Element} element
   * @param {string} id
   */
  createPermalinkSpan(element, id) {
    const permalinkEl = this.dom.createChildOf(element, 'span', 'lh-permalink');
    permalinkEl.id = id;
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = CategoryRenderer;
} else {
  self.CategoryRenderer = CategoryRenderer;
}
;
/**
 * @license
 * Copyright 2018 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* globals self, Util, CategoryRenderer */

/** @typedef {import('./dom.js')} DOM */

class PerformanceCategoryRenderer extends CategoryRenderer {
  /**
   * @param {LH.ReportResult.AuditRef} audit
   * @return {Element}
   */
  _renderMetric(audit) {
    const tmpl = this.dom.cloneTemplate('#tmpl-lh-metric', this.templateContext);
    const element = this.dom.find('.lh-metric', tmpl);
    element.id = audit.result.id;
    const rating = Util.calculateRating(audit.result.score, audit.result.scoreDisplayMode);
    element.classList.add(`lh-metric--${rating}`);

    const titleEl = this.dom.find('.lh-metric__title', tmpl);
    titleEl.textContent = audit.result.title;

    const valueEl = this.dom.find('.lh-metric__value', tmpl);
    valueEl.textContent = audit.result.displayValue || '';

    const descriptionEl = this.dom.find('.lh-metric__description', tmpl);
    descriptionEl.appendChild(this.dom.convertMarkdownLinkSnippets(audit.result.description));

    if (audit.result.scoreDisplayMode === 'error') {
      descriptionEl.textContent = '';
      valueEl.textContent = 'Error!';
      const tooltip = this.dom.createChildOf(descriptionEl, 'span');
      tooltip.textContent = audit.result.errorMessage || 'Report error: no metric information';
    }

    return element;
  }

  /**
   * @param {LH.ReportResult.AuditRef} audit
   * @param {number} scale
   * @return {Element}
   */
  _renderOpportunity(audit, scale) {
    const oppTmpl = this.dom.cloneTemplate('#tmpl-lh-opportunity', this.templateContext);
    const element = this.populateAuditValues(audit, oppTmpl);
    element.id = audit.result.id;

    if (!audit.result.details || audit.result.scoreDisplayMode === 'error') {
      return element;
    }
    const details = audit.result.details;
    if (details.type !== 'opportunity') {
      return element;
    }

    // Overwrite the displayValue with opportunity's wastedMs
    const displayEl = this.dom.find('.lh-audit__display-text', element);
    const sparklineWidthPct = `${details.overallSavingsMs / scale * 100}%`;
    this.dom.find('.lh-sparkline__bar', element).style.width = sparklineWidthPct;
    displayEl.textContent = Util.formatSeconds(details.overallSavingsMs, 0.01);

    // Set [title] tooltips
    if (audit.result.displayValue) {
      const displayValue = audit.result.displayValue;
      this.dom.find('.lh-load-opportunity__sparkline', element).title = displayValue;
      displayEl.title = displayValue;
    }

    return element;
  }

  /**
   * Get an audit's wastedMs to sort the opportunity by, and scale the sparkline width
   * Opportunities with an error won't have a details object, so MIN_VALUE is returned to keep any
   * erroring opportunities last in sort order.
   * @param {LH.ReportResult.AuditRef} audit
   * @return {number}
   */
  _getWastedMs(audit) {
    if (audit.result.details && audit.result.details.type === 'opportunity') {
      const details = audit.result.details;
      if (typeof details.overallSavingsMs !== 'number') {
        throw new Error('non-opportunity details passed to _getWastedMs');
      }
      return details.overallSavingsMs;
    } else {
      return Number.MIN_VALUE;
    }
  }

  /**
   * @param {LH.ReportResult.Category} category
   * @param {Object<string, LH.Result.ReportGroup>} groups
   * @param {'PSI'=} environment 'PSI' and undefined are the only valid values
   * @return {Element}
   * @override
   */
  render(category, groups, environment) {
    const element = this.dom.createElement('div', 'lh-category');
    if (environment === 'PSI') {
      const gaugeEl = this.dom.createElement('div', 'lh-score__gauge');
      gaugeEl.appendChild(this.renderScoreGauge(category, groups));
      element.appendChild(gaugeEl);
    } else {
      this.createPermalinkSpan(element, category.id);
      element.appendChild(this.renderCategoryHeader(category, groups));
    }

    // Metrics.
    const metricAuditsEl = this.renderAuditGroup(groups.metrics);

    // Metric descriptions toggle.
    const toggleTmpl = this.dom.cloneTemplate('#tmpl-lh-metrics-toggle', this.templateContext);
    const _toggleEl = this.dom.find('.lh-metrics-toggle', toggleTmpl);
    metricAuditsEl.append(..._toggleEl.childNodes);

    const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
    const keyMetrics = metricAudits.filter(a => a.weight >= 3);
    const otherMetrics = metricAudits.filter(a => a.weight < 3);

    const metricsBoxesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-columns');
    const metricsColumn1El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-column');
    const metricsColumn2El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-column');

    keyMetrics.forEach(item => {
      metricsColumn1El.appendChild(this._renderMetric(item));
    });
    otherMetrics.forEach(item => {
      metricsColumn2El.appendChild(this._renderMetric(item));
    });

    // 'Values are estimated and may vary' is used as the category description for PSI
    if (environment !== 'PSI') {
      const estValuesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metrics__disclaimer');
      const disclaimerEl = this.dom.convertMarkdownLinkSnippets(Util.UIStrings.varianceDisclaimer);
      estValuesEl.appendChild(disclaimerEl);
    }

    metricAuditsEl.classList.add('lh-audit-group--metrics');
    element.appendChild(metricAuditsEl);

    // Filmstrip
    const timelineEl = this.dom.createChildOf(element, 'div', 'lh-filmstrip-container');
    const thumbnailAudit = category.auditRefs.find(audit => audit.id === 'screenshot-thumbnails');
    const thumbnailResult = thumbnailAudit && thumbnailAudit.result;
    if (thumbnailResult && thumbnailResult.details) {
      timelineEl.id = thumbnailResult.id;
      const filmstripEl = this.detailsRenderer.render(thumbnailResult.details);
      filmstripEl && timelineEl.appendChild(filmstripEl);
    }

    // Budgets
    const budgetAudit = category.auditRefs.find(audit => audit.id === 'performance-budget');
    if (budgetAudit && budgetAudit.result.details) {
      const table = this.detailsRenderer.render(budgetAudit.result.details);
      if (table) {
        table.id = budgetAudit.id;
        table.classList.add('lh-audit');
        const budgetsGroupEl = this.renderAuditGroup(groups.budgets);
        budgetsGroupEl.appendChild(table);
        budgetsGroupEl.classList.add('lh-audit-group--budgets');
        element.appendChild(budgetsGroupEl);
      }
    }

    // Opportunities
    const opportunityAudits = category.auditRefs
        .filter(audit => audit.group === 'load-opportunities' && !Util.showAsPassed(audit.result))
        .sort((auditA, auditB) => this._getWastedMs(auditB) - this._getWastedMs(auditA));

    if (opportunityAudits.length) {
      // Scale the sparklines relative to savings, minimum 2s to not overstate small savings
      const minimumScale = 2000;
      const wastedMsValues = opportunityAudits.map(audit => this._getWastedMs(audit));
      const maxWaste = Math.max(...wastedMsValues);
      const scale = Math.max(Math.ceil(maxWaste / 1000) * 1000, minimumScale);
      const groupEl = this.renderAuditGroup(groups['load-opportunities']);
      const tmpl = this.dom.cloneTemplate('#tmpl-lh-opportunity-header', this.templateContext);

      this.dom.find('.lh-load-opportunity__col--one', tmpl).textContent =
        Util.UIStrings.opportunityResourceColumnLabel;
      this.dom.find('.lh-load-opportunity__col--two', tmpl).textContent =
        Util.UIStrings.opportunitySavingsColumnLabel;

      const headerEl = this.dom.find('.lh-load-opportunity__header', tmpl);
      groupEl.appendChild(headerEl);
      opportunityAudits.forEach(item => groupEl.appendChild(this._renderOpportunity(item, scale)));
      groupEl.classList.add('lh-audit-group--load-opportunities');
      element.appendChild(groupEl);
    }

    // Diagnostics
    const diagnosticAudits = category.auditRefs
        .filter(audit => audit.group === 'diagnostics' && !Util.showAsPassed(audit.result))
        .sort((a, b) => {
          const scoreA = a.result.scoreDisplayMode === 'informative' ? 100 : Number(a.result.score);
          const scoreB = b.result.scoreDisplayMode === 'informative' ? 100 : Number(b.result.score);
          return scoreA - scoreB;
        });

    if (diagnosticAudits.length) {
      const groupEl = this.renderAuditGroup(groups['diagnostics']);
      diagnosticAudits.forEach(item => groupEl.appendChild(this.renderAudit(item)));
      groupEl.classList.add('lh-audit-group--diagnostics');
      element.appendChild(groupEl);
    }

    // Passed audits
    const passedAudits = category.auditRefs
        .filter(audit => (audit.group === 'load-opportunities' || audit.group === 'diagnostics') &&
            Util.showAsPassed(audit.result));

    if (!passedAudits.length) return element;

    const clumpOpts = {
      auditRefs: passedAudits,
      groupDefinitions: groups,
    };
    const passedElem = this.renderClump('passed', clumpOpts);
    element.appendChild(passedElem);
    return element;
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = PerformanceCategoryRenderer;
} else {
  self.PerformanceCategoryRenderer = PerformanceCategoryRenderer;
}
;
/**
 * @license
 * Copyright 2018 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/* globals self, Util, CategoryRenderer */

/**
 * An always-increasing counter for making unique SVG ID suffixes.
 */
const getUniqueSuffix = (() => {
  let svgSuffix = 0;
  return function() {
    return svgSuffix++;
  };
})();

class PwaCategoryRenderer extends CategoryRenderer {
  /**
   * @param {LH.ReportResult.Category} category
   * @param {Object<string, LH.Result.ReportGroup>} [groupDefinitions]
   * @return {Element}
   */
  render(category, groupDefinitions = {}) {
    const categoryElem = this.dom.createElement('div', 'lh-category');
    this.createPermalinkSpan(categoryElem, category.id);
    categoryElem.appendChild(this.renderCategoryHeader(category, groupDefinitions));

    const auditRefs = category.auditRefs;

    // Regular audits aren't split up into pass/fail/notApplicable clumps, they're
    // all put in a top-level clump that isn't expandable/collapsible.
    const regularAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode !== 'manual');
    const auditsElem = this._renderAudits(regularAuditRefs, groupDefinitions);
    categoryElem.appendChild(auditsElem);

    // Manual audits are still in a manual clump.
    const manualAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode === 'manual');
    const manualElem = this.renderClump('manual',
      {auditRefs: manualAuditRefs, description: category.manualDescription});
    categoryElem.appendChild(manualElem);

    return categoryElem;
  }

  /**
   * @param {LH.ReportResult.Category} category
   * @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {DocumentFragment}
   */
  renderScoreGauge(category, groupDefinitions) {
    // Defer to parent-gauge style if category error.
    if (category.score === null) {
      return super.renderScoreGauge(category, groupDefinitions);
    }

    const tmpl = this.dom.cloneTemplate('#tmpl-lh-gauge--pwa', this.templateContext);
    const wrapper = /** @type {HTMLAnchorElement} */ (this.dom.find('.lh-gauge--pwa__wrapper',
      tmpl));
    wrapper.href = `#${category.id}`;

    // Correct IDs in case multiple instances end up in the page.
    const svgRoot = tmpl.querySelector('svg');
    if (!svgRoot) throw new Error('no SVG element found in PWA score gauge template');
    PwaCategoryRenderer._makeSvgReferencesUnique(svgRoot);

    const allGroups = this._getGroupIds(category.auditRefs);
    const passingGroupIds = this._getPassingGroupIds(category.auditRefs);

    if (passingGroupIds.size === allGroups.size) {
      wrapper.classList.add('lh-badged--all');
    } else {
      for (const passingGroupId of passingGroupIds) {
        wrapper.classList.add(`lh-badged--${passingGroupId}`);
      }
    }

    this.dom.find('.lh-gauge__label', tmpl).textContent = category.title;
    wrapper.title = this._getGaugeTooltip(category.auditRefs, groupDefinitions);
    return tmpl;
  }

  /**
   * Returns the group IDs found in auditRefs.
   * @param {Array<LH.ReportResult.AuditRef>} auditRefs
   * @return {Set<string>}
   */
  _getGroupIds(auditRefs) {
    const groupIds = auditRefs.map(ref => ref.group).filter(/** @return {g is string} */ g => !!g);
    return new Set(groupIds);
  }

  /**
   * Returns the group IDs whose audits are all considered passing.
   * @param {Array<LH.ReportResult.AuditRef>} auditRefs
   * @return {Set<string>}
   */
  _getPassingGroupIds(auditRefs) {
    const uniqueGroupIds = this._getGroupIds(auditRefs);

    // Remove any that have a failing audit.
    for (const auditRef of auditRefs) {
      if (!Util.showAsPassed(auditRef.result) && auditRef.group) {
        uniqueGroupIds.delete(auditRef.group);
      }
    }

    return uniqueGroupIds;
  }

  /**
   * Returns a tooltip string summarizing group pass rates.
   * @param {Array<LH.ReportResult.AuditRef>} auditRefs
   * @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {string}
   */
  _getGaugeTooltip(auditRefs, groupDefinitions) {
    const groupIds = this._getGroupIds(auditRefs);

    const tips = [];
    for (const groupId of groupIds) {
      const groupAuditRefs = auditRefs.filter(ref => ref.group === groupId);
      const auditCount = groupAuditRefs.length;
      const passedCount = groupAuditRefs.filter(ref => Util.showAsPassed(ref.result)).length;

      const title = groupDefinitions[groupId].title;
      tips.push(`${title}: ${passedCount}/${auditCount}`);
    }

    return tips.join(', ');
  }

  /**
   * Render non-manual audits in groups, giving a badge to any group that has
   * all passing audits.
   * @param {Array<LH.ReportResult.AuditRef>} auditRefs
   * @param {Object<string, LH.Result.ReportGroup>} groupDefinitions
   * @return {Element}
   */
  _renderAudits(auditRefs, groupDefinitions) {
    const auditsElem = this.renderUnexpandableClump(auditRefs, groupDefinitions);

    // Add a 'badged' class to group if all audits in that group pass.
    const passsingGroupIds = this._getPassingGroupIds(auditRefs);
    for (const groupId of passsingGroupIds) {
      const groupElem = this.dom.find(`.lh-audit-group--${groupId}`, auditsElem);
      groupElem.classList.add('lh-badged');
    }

    return auditsElem;
  }

  /**
   * Alters SVG id references so multiple instances of an SVG element can coexist
   * in a single page. If `svgRoot` has a `<defs>` block, gives all elements defined
   * in it unique ids, then updates id references (`<use xlink:href="...">`,
   * `fill="url(#...)"`) to the altered ids in all descendents of `svgRoot`.
   * @param {SVGElement} svgRoot
   */
  static _makeSvgReferencesUnique(svgRoot) {
    const defsEl = svgRoot.querySelector('defs');
    if (!defsEl) return;

    const idSuffix = getUniqueSuffix();
    const elementsToUpdate = defsEl.querySelectorAll('[id]');
    for (const el of elementsToUpdate) {
      const oldId = el.id;
      const newId = `${oldId}-${idSuffix}`;
      el.id = newId;

      // Update all <use>s.
      const useEls = svgRoot.querySelectorAll(`use[href="#${oldId}"]`);
      for (const useEl of useEls) {
        useEl.setAttribute('href', `#${newId}`);
      }

      // Update all fill="url(#...)"s.
      const fillEls = svgRoot.querySelectorAll(`[fill="url(#${oldId})"]`);
      for (const fillEl of fillEls) {
        fillEl.setAttribute('fill', `url(#${newId})`);
      }
    }
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = PwaCategoryRenderer;
} else {
  self.PwaCategoryRenderer = PwaCategoryRenderer;
}
;
/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

/**
 * @fileoverview The entry point for rendering the Lighthouse report based on the JSON output.
 *    This file is injected into the report HTML along with the JSON report.
 *
 * Dummy text for ensuring report robustness: \u003c/script> pre$`post %%LIGHTHOUSE_JSON%%
 */

/** @typedef {import('./dom.js')} DOM */

/* globals self, Util, DetailsRenderer, CategoryRenderer, PerformanceCategoryRenderer, PwaCategoryRenderer */

class ReportRenderer {
  /**
   * @param {DOM} dom
   */
  constructor(dom) {
    /** @type {DOM} */
    this._dom = dom;
    /** @type {ParentNode} */
    this._templateContext = this._dom.document();
  }

  /**
   * @param {LH.Result} result
   * @param {Element} container Parent element to render the report into.
   * @return {Element}
   */
  renderReport(result, container) {
    // Mutate the UIStrings if necessary (while saving originals)
    const originalUIStrings = JSON.parse(JSON.stringify(Util.UIStrings));

    this._dom.setLighthouseChannel(result.configSettings.channel || 'unknown');

    const report = Util.prepareReportResult(result);

    container.textContent = ''; // Remove previous report.
    container.appendChild(this._renderReport(report));

    // put the UIStrings back into original state
    Util.updateAllUIStrings(originalUIStrings);

    return container;
  }

  /**
   * Define a custom element for <templates> to be extracted from. For example:
   *     this.setTemplateContext(new DOMParser().parseFromString(htmlStr, 'text/html'))
   * @param {ParentNode} context
   */
  setTemplateContext(context) {
    this._templateContext = context;
  }

  /**
   * @param {LH.ReportResult} report
   * @return {DocumentFragment}
   */
  _renderReportTopbar(report) {
    const el = this._dom.cloneTemplate('#tmpl-lh-topbar', this._templateContext);
    const metadataUrl = /** @type {HTMLAnchorElement} */ (this._dom.find('.lh-topbar__url', el));
    metadataUrl.href = metadataUrl.textContent = report.finalUrl;
    metadataUrl.title = report.finalUrl;
    return el;
  }

  /**
   * @return {DocumentFragment}
   */
  _renderReportHeader() {
    const el = this._dom.cloneTemplate('#tmpl-lh-heading', this._templateContext);
    const domFragment = this._dom.cloneTemplate('#tmpl-lh-scores-wrapper', this._templateContext);
    const placeholder = this._dom.find('.lh-scores-wrapper-placeholder', el);
    /** @type {HTMLDivElement} */ (placeholder.parentNode).replaceChild(domFragment, placeholder);
    return el;
  }

  /**
   * @param {LH.ReportResult} report
   * @return {DocumentFragment}
   */
  _renderReportFooter(report) {
    const footer = this._dom.cloneTemplate('#tmpl-lh-footer', this._templateContext);

    const env = this._dom.find('.lh-env__items', footer);
    env.id = 'runtime-settings';
    const envValues = Util.getEnvironmentDisplayValues(report.configSettings || {});
    [
      {name: 'URL', description: report.finalUrl},
      {name: 'Fetch time', description: Util.formatDateTime(report.fetchTime)},
      ...envValues,
      {name: 'User agent (host)', description: report.userAgent},
      {name: 'User agent (network)', description: report.environment &&
        report.environment.networkUserAgent},
      {name: 'CPU/Memory Power', description: report.environment &&
        report.environment.benchmarkIndex.toFixed(0)},
    ].forEach(runtime => {
      if (!runtime.description) return;

      const item = this._dom.cloneTemplate('#tmpl-lh-env__items', env);
      this._dom.find('.lh-env__name', item).textContent = runtime.name;
      this._dom.find('.lh-env__description', item).textContent = runtime.description;
      env.appendChild(item);
    });

    this._dom.find('.lh-footer__version', footer).textContent = report.lighthouseVersion;
    return footer;
  }

  /**
   * Returns a div with a list of top-level warnings, or an empty div if no warnings.
   * @param {LH.ReportResult} report
   * @return {Node}
   */
  _renderReportWarnings(report) {
    if (!report.runWarnings || report.runWarnings.length === 0) {
      return this._dom.createElement('div');
    }

    const container = this._dom.cloneTemplate('#tmpl-lh-warnings--toplevel', this._templateContext);
    const message = this._dom.find('.lh-warnings__msg', container);
    message.textContent = Util.UIStrings.toplevelWarningsMessage;

    const warnings = this._dom.find('ul', container);
    for (const warningString of report.runWarnings) {
      const warning = warnings.appendChild(this._dom.createElement('li'));
      warning.textContent = warningString;
    }

    return container;
  }

  /**
   * @param {LH.ReportResult} report
   * @param {CategoryRenderer} categoryRenderer
   * @param {Record<string, CategoryRenderer>} specificCategoryRenderers
   * @return {DocumentFragment[]}
   */
  _renderScoreGauges(report, categoryRenderer, specificCategoryRenderers) {
    // Group gauges in this order: default, pwa, plugins.
    const defaultGauges = [];
    const customGauges = []; // PWA.
    const pluginGauges = [];

    for (const category of Object.values(report.categories)) {
      const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
      const categoryGauge = renderer.renderScoreGauge(category, report.categoryGroups || {});

      if (Util.isPluginCategory(category.id)) {
        pluginGauges.push(categoryGauge);
      } else if (renderer.renderScoreGauge === categoryRenderer.renderScoreGauge) {
        // The renderer for default categories is just the default CategoryRenderer.
        // If the functions are equal, then renderer is an instance of CategoryRenderer.
        // For example, the PWA category uses PwaCategoryRenderer, which overrides
        // CategoryRenderer.renderScoreGauge, so it would fail this check and be placed
        // in the customGauges bucket.
        defaultGauges.push(categoryGauge);
      } else {
        customGauges.push(categoryGauge);
      }
    }

    return [...defaultGauges, ...customGauges, ...pluginGauges];
  }

  /**
   * @param {LH.ReportResult} report
   * @return {DocumentFragment}
   */
  _renderReport(report) {
    const detailsRenderer = new DetailsRenderer(this._dom);
    const categoryRenderer = new CategoryRenderer(this._dom, detailsRenderer);
    categoryRenderer.setTemplateContext(this._templateContext);

    /** @type {Record<string, CategoryRenderer>} */
    const specificCategoryRenderers = {
      performance: new PerformanceCategoryRenderer(this._dom, detailsRenderer),
      pwa: new PwaCategoryRenderer(this._dom, detailsRenderer),
    };
    Object.values(specificCategoryRenderers).forEach(renderer => {
      renderer.setTemplateContext(this._templateContext);
    });

    const headerContainer = this._dom.createElement('div');
    headerContainer.appendChild(this._renderReportHeader());

    const reportContainer = this._dom.createElement('div', 'lh-container');
    const reportSection = this._dom.createElement('div', 'lh-report');
    reportSection.appendChild(this._renderReportWarnings(report));

    let scoreHeader;
    const isSoloCategory = Object.keys(report.categories).length === 1;
    if (!isSoloCategory) {
      scoreHeader = this._dom.createElement('div', 'lh-scores-header');
    } else {
      headerContainer.classList.add('lh-header--solo-category');
    }

    if (scoreHeader) {
      const scoreScale = this._dom.cloneTemplate('#tmpl-lh-scorescale', this._templateContext);
      const scoresContainer = this._dom.find('.lh-scores-container', headerContainer);
      scoreHeader.append(
        ...this._renderScoreGauges(report, categoryRenderer, specificCategoryRenderers));
      scoresContainer.appendChild(scoreHeader);
      scoresContainer.appendChild(scoreScale);

      const stickyHeader = this._dom.createElement('div', 'lh-sticky-header');
      stickyHeader.append(
        ...this._renderScoreGauges(report, categoryRenderer, specificCategoryRenderers));
      reportContainer.appendChild(stickyHeader);
    }

    const categories = reportSection.appendChild(this._dom.createElement('div', 'lh-categories'));
    for (const category of Object.values(report.categories)) {
      const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
      // .lh-category-wrapper is full-width and provides horizontal rules between categories.
      // .lh-category within has the max-width: var(--report-width);
      const wrapper = renderer.dom.createChildOf(categories, 'div', 'lh-category-wrapper');
      wrapper.appendChild(renderer.render(category, report.categoryGroups));
    }

    const reportFragment = this._dom.createFragment();
    const topbarDocumentFragment = this._renderReportTopbar(report);

    reportFragment.appendChild(topbarDocumentFragment);
    reportFragment.appendChild(reportContainer);
    reportContainer.appendChild(headerContainer);
    reportContainer.appendChild(reportSection);
    reportSection.appendChild(this._renderReportFooter(report));

    return reportFragment;
  }
}

/** @type {LH.I18NRendererStrings} */
ReportRenderer._UIStringsStash = {};

if (typeof module !== 'undefined' && module.exports) {
  module.exports = ReportRenderer;
} else {
  self.ReportRenderer = ReportRenderer;
}

  //# sourceURL=compiled-reportrenderer.js
  </script>
  <script>window.__LIGHTHOUSE_JSON__ = {"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/80.0.3987.149 Safari/537.36","environment":{"networkUserAgent":"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3694.0 Mobile Safari/537.36 Chrome-Lighthouse","hostUserAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/80.0.3987.149 Safari/537.36","benchmarkIndex":1466},"lighthouseVersion":"5.6.0","fetchTime":"2020-03-24T09:39:05.277Z","requestedUrl":"https://www.baidu.com/","finalUrl":"https://www.baidu.com/","runWarnings":[],"audits":{"is-on-https":{"id":"is-on-https","title":"未使用 HTTPS","description":"应该使用 HTTPS 保护所有网站（包括不会处理敏感数据的网站）。HTTPS 可防止入侵程序篡改或被动地监听您的应用与用户之间的通信，它是HTTP/2 和许多新的网络平台 API 的先决条件。[了解详情](https://web.dev/is-on-https)。","score":0,"scoreDisplayMode":"binary","displayValue":"发现 2 条不安全的请求","details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"不安全的网址"}],"items":[{"url":"baiduboxlite://utils?action=sendIntent&minver=3.3&params=%7B%22intent%22%3A%22intent%3A%23Intent%3Baction%3Dcom.baidu.searchbox.action.HOME%3Bpackage%3Dcom.baidu.searchbox.lite%3BS.targetCommand%3D%257B%2522mode%2522%253A%25220%2522%252C%2522intent%2522%253A%2522intent%253A%2523Intent%253Baction%253Dcom.baidu.searchbox.action.HOME%253Bcategory%253Dandroid.intent.category.DEFAULT%253BS.extra_target_tab%253DFeed%253Bend%2522%252C%2522min_v%2522%253A%252220120832%2522%257D%3Bend%22%7D&needlog=1&logargs=%7B%22source%22%3A%221021206d%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22chrome%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22%22%2C%22channel%22%3A%221021206r%22%2C%22extlog%22%3A%22%22%2C%22baiduId%22%3A%2288C7BD6C60D47AD71CFBE516CB4A166B%3AFG%3D1%22%2C%22app_now%22%3A%22chrome_1585042749079_3561962775%22%2C%22yyb_pkg%22%3A%22com.baidu.searchbox%22%2C%22idmData%22%3A%7B%22firstOpen%22%3A%22lite%22%2C%22secondOpen%22%3A%22main%22%2C%22status%22%3A%220%22%2C%22timeout%22%3A1585129147042%7D%2C%22matrix%22%3A%22lite%22%7D"},{"url":"baiduboxapp://utils?action=sendIntent&minver=7.4&params=%7B%22intent%22%3A%22intent%3A%23Intent%3Baction%3Dcom.baidu.searchbox.action.HOME%3Bpackage%3Dcom.baidu.searchbox%3BS.targetCommand%3D%257B%2522mode%2522%253A%25220%2522%252C%2522intent%2522%253A%2522intent%253A%2523Intent%253Baction%253Dcom.baidu.searchbox.action.HOME%253Bcategory%253Dandroid.intent.category.DEFAULT%253BS.extra_target_tab%253DFeed%253Bend%2522%252C%2522min_v%2522%253A%252216787968%2522%257D%3Bend%22%7D&needlog=1&logargs=%7B%22source%22%3A%221021206d%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22chrome%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22%22%2C%22channel%22%3A%221021206r%22%2C%22extlog%22%3A%22%22%2C%22baiduId%22%3A%2288C7BD6C60D47AD71CFBE516CB4A166B%3AFG%3D1%22%2C%22app_now%22%3A%22chrome_1585042749222_5861823275%22%2C%22yyb_pkg%22%3A%22com.baidu.searchbox%22%2C%22idmData%22%3A%7B%22firstOpen%22%3A%22lite%22%2C%22secondOpen%22%3A%22main%22%2C%22status%22%3A%220%22%2C%22timeout%22%3A1585129147042%7D%2C%22matrix%22%3A%22main%22%7D"}]}},"redirects-http":{"id":"redirects-http","title":"未将 HTTP 流量重定向到 HTTPS","description":"如果您已设置 HTTPS，请确保将所有 HTTP 流量重定向到 HTTPS，以便让所有用户都能使用安全的网络功能。[了解详情](https://web.dev/redirects-http)。","score":0,"scoreDisplayMode":"binary"},"service-worker":{"id":"service-worker","title":"无法注册用于控制网页和 `start_url` 的 Service Worker","description":"Service Worker 是一项技术，可让您的应用使用很多渐进式 Web 应用功能，例如离线、添加到主屏幕和推送通知。[了解详情](https://web.dev/service-worker)。","score":0,"scoreDisplayMode":"binary"},"works-offline":{"id":"works-offline","title":"当前网页在离线时没有响应，并返回 200","description":"如果您想构建渐进式 Web 应用，不妨考虑使用 Service Worker，以确保您的应用可离线工作。[了解详情](https://web.dev/works-offline)。","score":0,"scoreDisplayMode":"binary","warnings":[]},"viewport":{"id":"viewport","title":"具有包含 `width` 或 `initial-scale` 的 `\u003cmeta name=\"viewport\">` 标记","description":"添加 `\u003cmeta name=\"viewport\">` 标记以针对移动设备屏幕优化您的应用。[了解详情](https://web.dev/viewport)。","score":1,"scoreDisplayMode":"binary","warnings":[]},"without-javascript":{"id":"without-javascript","title":"包含一些 JavaScript 未启用时显示的内容","description":"您的应用应该在 JavaScript 被禁用时显示一些内容，哪怕只是向用户显示一则警告（告知其必须启用 JavaScript 才能使用该应用）。[了解详情](https://web.dev/without-javascript)。","score":1,"scoreDisplayMode":"binary"},"first-contentful-paint":{"id":"first-contentful-paint","title":"首次内容绘制时间","description":"首次内容渲染时间标记了渲染出首个文本或首张图片的时间。[了解详情](https://web.dev/first-contentful-paint)。","score":0.99,"scoreDisplayMode":"numeric","numericValue":1484.948,"displayValue":"1.5 秒"},"first-meaningful-paint":{"id":"first-meaningful-paint","title":"首次有效绘制时间","description":"首次有效渲染时间测量了网页主要内容开始对用户显示的时间。[了解详情](https://web.dev/first-meaningful-paint)。","score":0.63,"scoreDisplayMode":"numeric","numericValue":3473.8365000000003,"displayValue":"3.5 秒"},"load-fast-enough-for-pwa":{"id":"load-fast-enough-for-pwa","title":"页面在移动网络上的加载速度足够快","description":"如果网页在移动网络中的加载速度较快，则可确保良好的移动用户体验。[了解详情](https://web.dev/load-fast-enough-for-pwa)。","score":1,"scoreDisplayMode":"binary","numericValue":6774.141},"speed-index":{"id":"speed-index","title":"速度指数","description":"速度指数表明了网页内容的可见填充速度。[了解详情](https://web.dev/speed-index)。","score":0.66,"scoreDisplayMode":"numeric","numericValue":4868.80627679871,"displayValue":"4.9 秒"},"screenshot-thumbnails":{"id":"screenshot-thumbnails","title":"Screenshot Thumbnails","description":"This is what the load of your site looked like.","score":null,"scoreDisplayMode":"informative","details":{"type":"filmstrip","scale":3320,"items":[{"timing":332,"timestamp":370270516970,"data":""},{"timing":664,"timestamp":370270848970,"data":""},{"timing":996,"timestamp":370271180970,"data":""},{"timing":1328,"timestamp":370271512970,"data":""},{"timing":1660,"timestamp":370271844970,"data":""},{"timing":1992,"timestamp":370272176970,"data":""},{"timing":2324,"timestamp":370272508970,"data":""},{"timing":2656,"timestamp":370272840970,"data":""},{"timing":2988,"timestamp":370273172970,"data":""},{"timing":3320,"timestamp":370273504970,"data":""}]}},"final-screenshot":{"id":"final-screenshot","title":"Final Screenshot","description":"The last screenshot captured of the pageload.","score":null,"scoreDisplayMode":"informative","details":{"type":"screenshot","timing":3320,"timestamp":370273505134,"data":""}},"estimated-input-latency":{"id":"estimated-input-latency","title":"输入延迟（估算值）","description":"预计输入延迟是估算值，表示您的应用在网页加载最繁忙的 5 秒期间大概需要花费多长时间（以毫秒为单位）才能对用户输入做出响应。如果您的延迟时间超过了 50 毫秒，用户可能会感觉您的应用运行迟缓。[了解详情](https://web.dev/estimated-input-latency)。","score":0.99,"scoreDisplayMode":"numeric","numericValue":34,"displayValue":"30 毫秒"},"total-blocking-time":{"id":"total-blocking-time","title":"总阻塞时间","description":"当任务长度超过 50 毫秒时，首次内容渲染 (FCP) 和可交互时间之间的所有时间段的总和，以毫秒表示。","score":0.77,"scoreDisplayMode":"numeric","numericValue":395.5,"displayValue":"400 毫秒"},"max-potential-fid":{"id":"max-potential-fid","title":"首次输入延迟最长预估值","description":"您的用户可能会遇到的最长首次输入延迟是用时最长的任务的耗时（以毫秒为单位）。[了解详情](https://developers.google.com/web/updates/2018/05/first-input-delay)。","score":0.51,"scoreDisplayMode":"numeric","numericValue":247,"displayValue":"250 毫秒"},"errors-in-console":{"id":"errors-in-console","title":"控制台日志中已记录浏览器错误","description":"控制台中记录的错误表明有未解决的问题。导致这些错误的可能原因是网络请求失败和其他浏览器问题。[了解详情](https://web.dev/errors-in-console)","score":0,"scoreDisplayMode":"binary","numericValue":1,"details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"网址"},{"key":"description","itemType":"code","text":"说明"}],"items":[{"source":"network","description":"Failed to load resource: net::ERR_CONNECTION_REFUSED","url":"http://127.0.0.1:59468/?data=fCMxIzsjMi8xLzUjLSMyIzsjbVRmW1ZlT3daWElUN1cyZFQzNm15VHZ5Y3k3dGhCentWOm1HMXRNa1lXaVZTdmpuOlFpczVvNEVGNVosS1JLd1VnW3l2eFpFQ3lbbzlmNk1Na3A6Y0I%2BPiMtIzMjOyM5NTVjfSMtIzQjOzI2OTYxNTM4NTc6MjF%2B"}]}},"time-to-first-byte":{"id":"time-to-first-byte","title":"服务器响应用时较短 (TTFB)","description":"首字节显示前的耗时表明了服务器发出响应的时间。[了解详情](https://web.dev/time-to-first-byte)。","score":1,"scoreDisplayMode":"binary","numericValue":114.52599999999995,"displayValue":"根文档花费了 110 毫秒","details":{"type":"opportunity","overallSavingsMs":-485.47400000000005,"headings":[],"items":[]}},"first-cpu-idle":{"id":"first-cpu-idle","title":"首次 CPU 闲置时间","description":"首次 CPU 闲置时间标记了网页的主线程首次有空处理输入操作的时间。[了解详情](https://web.dev/first-cpu-idle)。","score":0.62,"scoreDisplayMode":"numeric","numericValue":5617.4839999999995,"displayValue":"5.6 秒"},"interactive":{"id":"interactive","title":"可交互前的耗时","description":"可交互时间是指网页需要多长时间才能提供完整交互功能。[了解详情](https://web.dev/interactive)。","score":0.56,"scoreDisplayMode":"numeric","numericValue":6774.141,"displayValue":"6.8 秒"},"user-timings":{"id":"user-timings","title":"User Timing 标记和测量结果","description":"建议使用 User Timing API 检测您的应用，从而衡量应用在关键用户体验中的实际性能。[了解详情](https://web.dev/user-timings)。","score":null,"scoreDisplayMode":"notApplicable","details":{"type":"table","headings":[],"items":[]}},"critical-request-chains":{"id":"critical-request-chains","title":"最大限度地缩短关键请求深度","description":"下面的关键请求链显示了以高优先级加载的资源。请考虑缩短链长、缩减资源的下载文件大小，或者推迟下载不必要的资源，从而提高网页加载速度。[了解详情](https://web.dev/critical-request-chains)。","score":null,"scoreDisplayMode":"informative","displayValue":"找到了 2 条请求链","details":{"type":"criticalrequestchain","chains":{"873380A842E6FB30C8C0D86CAE3DB801":{"request":{"url":"https://www.baidu.com/","startTime":370270.186134,"endTime":370270.764733,"responseReceivedTime":370270.677933,"transferSize":90780},"children":{"28468.4":{"request":{"url":"https://sm.bdimg.com/static/wiseindex/fonts/n-icons_7bcbf44.woff","startTime":370270.784883,"endTime":370270.837015,"responseReceivedTime":370270.82867,"transferSize":43313}},"28468.63":{"request":{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/base/uilib/iconfont/iconfont_fcd5aba.woff?","startTime":370271.684762,"endTime":370271.723411,"responseReceivedTime":370271.721197,"transferSize":29718}}}}},"longestChain":{"duration":1537.276999966707,"length":2,"transferSize":29718}}},"redirects":{"id":"redirects","title":"避免多次网页重定向","description":"重定向会在网页可加载前引入更多延迟。[了解详情](https://web.dev/redirects)。","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"","details":{"type":"opportunity","headings":[],"items":[],"overallSavingsMs":0}},"installable-manifest":{"id":"installable-manifest","title":"Web 应用清单不符合可安装性要求","description":"浏览器可主动提示用户向其主屏幕中添加您的应用，这有助于提高互动度。[了解详情](https://web.dev/installable-manifest)。","score":0,"scoreDisplayMode":"binary","explanation":"Failures: No manifest was fetched.","details":{"type":"debugdata","items":[{"failures":["No manifest was fetched"],"isParseFailure":true,"parseFailureReason":"No manifest was fetched"}]}},"apple-touch-icon":{"id":"apple-touch-icon","title":"提供了有效的 `apple-touch-icon`","description":"请定义一个 `apple-touch-icon`，以在 iOS 用户向主屏幕添加渐进式 Web 应用时获得理想的外观。它必须指向一张不透明的 192px（或 180px）方形 PNG 图片。[了解详情](https://web.dev/apple-touch-icon/)。","score":1,"scoreDisplayMode":"binary","warnings":["`apple-touch-icon-precomposed` 不是最新版本，建议使用 `apple-touch-icon`。"]},"splash-screen":{"id":"splash-screen","title":"未针对自定义启动画面进行配置","description":"选定主题的启动画面可确保用户在从主屏幕中启动您应用时获得优质体验。[了解详情](https://web.dev/splash-screen)。","score":0,"scoreDisplayMode":"binary","explanation":"Failures: No manifest was fetched.","details":{"type":"debugdata","items":[{"failures":["No manifest was fetched"],"isParseFailure":true,"parseFailureReason":"No manifest was fetched"}]}},"themed-omnibox":{"id":"themed-omnibox","title":"没有为地址栏设置主题背景颜色。","description":"可以为浏览器地址栏设置与您的网站相契合的主题背景。[了解详情](https://web.dev/themed-omnibox)。","score":0,"scoreDisplayMode":"binary","explanation":"Failures: No manifest was fetched,\nNo `\u003cmeta name=\"theme-color\">` tag found.","details":{"type":"debugdata","items":[{"failures":["No manifest was fetched","No `\u003cmeta name=\"theme-color\">` tag found"],"themeColor":null,"isParseFailure":true,"parseFailureReason":"No manifest was fetched"}]}},"content-width":{"id":"content-width","title":"已根据视口正确设置内容尺寸","description":"如果应用内容的宽度与视口的宽度不一致，该应用可能不会针对移动设备屏幕进行优化。[了解详情](https://web.dev/content-width)。","score":1,"scoreDisplayMode":"binary","explanation":""},"image-aspect-ratio":{"id":"image-aspect-ratio","title":"显示的图像宽高比正确","description":"图像显示尺寸应与自然宽高比相匹配。[了解详情](https://web.dev/image-aspect-ratio)。","score":1,"scoreDisplayMode":"binary","warnings":[],"details":{"type":"table","headings":[],"items":[]}},"deprecations":{"id":"deprecations","title":"请勿使用已弃用的 API","description":"已弃用的的 API 最终将从浏览器中移除。[了解详情](https://web.dev/deprecations)。","score":1,"scoreDisplayMode":"binary","displayValue":"","details":{"type":"table","headings":[],"items":[]}},"mainthread-work-breakdown":{"id":"mainthread-work-breakdown","title":"最大限度地减少主线程工作","description":"建议您减少为解析、编译和执行 JS 而花费的时间。您可能会发现，提供较小的 JS 负载有助于实现此目标。[了解详情](https://web.dev/mainthread-work-breakdown)","score":0.73,"scoreDisplayMode":"numeric","numericValue":2900.6039999999975,"displayValue":"2.9 秒","details":{"type":"table","headings":[{"key":"groupLabel","itemType":"text","text":"类别"},{"key":"duration","itemType":"ms","granularity":1,"text":"花费的时间"}],"items":[{"group":"scriptEvaluation","groupLabel":"Script Evaluation","duration":1085.0719999999965},{"group":"styleLayout","groupLabel":"Style & Layout","duration":766.5799999999998},{"group":"other","groupLabel":"Other","duration":648.960000000001},{"group":"scriptParseCompile","groupLabel":"Script Parsing & Compilation","duration":230.50400000000033},{"group":"paintCompositeRender","groupLabel":"Rendering","duration":104.912},{"group":"parseHTML","groupLabel":"Parse HTML & CSS","duration":64.576}]}},"bootup-time":{"id":"bootup-time","title":"JavaScript 执行用时","description":"建议您减少为解析、编译和执行 JS 而花费的时间。您可能会发现，提供较小的 JS 负载有助于实现此目标。[了解详情](https://web.dev/bootup-time)。","score":0.92,"scoreDisplayMode":"numeric","numericValue":1186.9880000000005,"displayValue":"1.2 秒","details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"网址"},{"key":"total","granularity":1,"itemType":"ms","text":"总 CPU 时间"},{"key":"scripting","granularity":1,"itemType":"ms","text":"脚本评估"},{"key":"scriptParseCompile","granularity":1,"itemType":"ms","text":"脚本解析"}],"items":[{"url":"Other","total":2153.9400000000005,"scripting":600.4960000000002,"scriptParseCompile":5.1480000000000015},{"url":"https://www.baidu.com/?action=static&ms=1&version=css_page_2@0,css_callapp@0,css_weather@0,css_icon@0,css_plus@0,css_edit@0,css_modal@0,css_widget_sug@0,css_skin@0,js_esl@0,js_zepto@0,js_event@0,js_fastclick@0,js_utils@0,js_smartymonkey@0,js_index@0,js_banner_ctrl@0,js_inputlog@0,js_bdnow@0,js_nctips@0,js_widget_textinput@0,js_widget_sug@0,js_mp@0,js_hash_lib@0,js_skinRenderIndex@0,js_skinIphone@0,js_prefetch@0,js_sug@0,js_iscroll@0,js_superframe@0,js_init@0,js_geolocation@0,js_login@0,js_tab@0,js_md5@0,js_url@0,js_lswrite@0,js_modal@0,js_thirdparty@0,js_m_monitor@0,js_superstart@0,js_baiduloc@0,js_callbaiduapp_android@0&callback=B.getCode&r=248&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085","total":468.20800000000014,"scripting":303.88800000000015,"scriptParseCompile":132.14800000000005},{"url":"https://www.baidu.com/","total":89.18799999999999,"scripting":69.66,"scriptParseCompile":14.967999999999995},{"url":"https://hm.baidu.com/hm.js?12423ecbc0e2ca965d84259063d35238","total":60.67999999999997,"scripting":57.65599999999997,"scriptParseCompile":3.0240000000000005}],"summary":{"wastedMs":1186.9880000000005}}},"uses-rel-preload":{"id":"uses-rel-preload","title":"预加载关键请求","description":"建议使用 `\u003clink rel=preload>` 来优先提取当前在网页加载后期请求的资源。[了解详情](https://web.dev/uses-rel-preload)。","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"","details":{"type":"opportunity","headings":[],"items":[],"overallSavingsMs":0}},"uses-rel-preconnect":{"id":"uses-rel-preconnect","title":"预先连接到必要的来源","description":"建议添加 `preconnect` 或 `dns-prefetch` 资源提示，以尽早与重要的第三方来源建立连接。[了解详情](https://web.dev/uses-rel-preconnect)。","score":0.73,"scoreDisplayMode":"numeric","numericValue":342.126,"displayValue":"有望节省 340 毫秒","warnings":[],"details":{"type":"opportunity","headings":[{"key":"url","valueType":"url","label":"网址"},{"key":"wastedMs","valueType":"timespanMs","label":"可能达到的节省程度"}],"items":[{"url":"https://hm.baidu.com","wastedMs":342.126},{"url":"https://feed.baidu.com","wastedMs":331.718},{"url":"https://ext.baidu.com","wastedMs":322.032},{"url":"https://ss1.baidu.com","wastedMs":307.576},{"url":"https://ss2.baidu.com","wastedMs":304.088},{"url":"https://gss0.bdstatic.com","wastedMs":301.76},{"url":"https://ss0.bdstatic.com","wastedMs":301.32199999999995},{"url":"https://s.bdstatic.com","wastedMs":300}],"overallSavingsMs":342.126}},"font-display":{"id":"font-display","title":"确保文本在网页字体加载期间保持可见状态","description":"利用 font-display 这项 CSS 功能，确保文本在网页字体加载期间始终对用户可见。[了解详情](https://web.dev/font-display)。","score":0,"scoreDisplayMode":"binary","warnings":[],"details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"网址"},{"key":"wastedMs","itemType":"ms","text":"可能达到的节省程度"}],"items":[{"url":"https://sm.bdimg.com/static/wiseindex/fonts/n-icons_7bcbf44.woff","wastedMs":52.13199998252094},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/base/uilib/iconfont/iconfont_fcd5aba.woff?","wastedMs":38.64899999462068}]}},"diagnostics":{"id":"diagnostics","title":"Diagnostics","description":"Collection of useful page vitals.","score":null,"scoreDisplayMode":"informative","details":{"type":"debugdata","items":[{"numRequests":99,"numScripts":48,"numStylesheets":0,"numFonts":2,"numTasks":1422,"numTasksOver10ms":13,"numTasksOver25ms":4,"numTasksOver50ms":4,"numTasksOver100ms":1,"numTasksOver500ms":0,"rtt":9.071000000000002,"throughput":16128237.425627457,"maxRtt":30.134,"maxServerLatency":75.54599999999999,"totalByteWeight":974958,"totalTaskTime":725.1510000000006,"mainDocumentTransferSize":90780}]}},"network-requests":{"id":"network-requests","title":"Network Requests","description":"Lists the network requests that were made during page load.","score":null,"scoreDisplayMode":"informative","numericValue":99,"details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"URL"},{"key":"startTime","itemType":"ms","granularity":1,"text":"Start Time"},{"key":"endTime","itemType":"ms","granularity":1,"text":"End Time"},{"key":"transferSize","itemType":"bytes","displayUnit":"kb","granularity":1,"text":"Transfer Size"},{"key":"resourceSize","itemType":"bytes","displayUnit":"kb","granularity":1,"text":"Resource Size"},{"key":"statusCode","itemType":"text","text":"Status Code"},{"key":"mimeType","itemType":"text","text":"MIME Type"},{"key":"resourceType","itemType":"text","text":"Resource Type"}],"items":[{"url":"https://www.baidu.com/","startTime":0,"endTime":578.5990000003949,"transferSize":90780,"resourceSize":206955,"statusCode":200,"mimeType":"text/html","resourceType":"Document"},{"url":"https://imgsa.baidu.com/normandy/pic/item/35a85edf8db1cb136e736049d254564e92584b55.jpg","startTime":529.9299999605864,"endTime":570.8289999747649,"transferSize":5364,"resourceSize":4911,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/static/index/plus/plus_logo_web.png","startTime":530.2239999873564,"endTime":704.260999977123,"transferSize":30099,"resourceSize":29628,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://imgsa.baidu.com/normandy/pic/item/a044ad345982b2b7f404309c3eadcbef77099bca.jpg","startTime":538.4089999715798,"endTime":574.434999958612,"transferSize":10232,"resourceSize":9862,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/bdlogo/squareicon_e582f4c48e93901e747536ad982e030d.png","startTime":538.6129999533296,"endTime":655.9099999722093,"transferSize":834,"resourceSize":369,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://sm.bdimg.com/static/wiseindex/fonts/n-icons_7bcbf44.woff","startTime":598.7489999970421,"endTime":650.8809999795631,"transferSize":43313,"resourceSize":43036,"statusCode":200,"mimeType":"application/octet-stream","resourceType":"Font"},{"url":"https://sm.bdimg.com/static/wiseindex/img/fetch_ing_8_0.png","startTime":603.7429999560118,"endTime":643.7109999824315,"transferSize":1161,"resourceSize":917,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://hpd.baidu.com/v.gif?tid=13&ct=1&cst=1&logFrom=index&logInfo=index&ssid=0&from=844b&pu=sz%40320_1001%2Cta%40iphone_2_6.0_24_74.0&qid=2346015140&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&logid=2346015140&ref=index_iphone&r=l1585042746509","startTime":610.5569999781437,"endTime":741.8099999777041,"transferSize":130,"resourceSize":0,"statusCode":200,"mimeType":"image/gif","resourceType":"Image"},{"url":"","startTime":613.095999986399,"endTime":613.1269999896176,"transferSize":0,"resourceSize":255,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/static/index/plus/public/icon_police.png","startTime":613.5249999933876,"endTime":684.6049999585375,"transferSize":3267,"resourceSize":2798,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://www.baidu.com/?action=static&ms=1&version=css_page_2@0,css_callapp@0,css_weather@0,css_icon@0,css_plus@0,css_edit@0,css_modal@0,css_widget_sug@0,css_skin@0,js_esl@0,js_zepto@0,js_event@0,js_fastclick@0,js_utils@0,js_smartymonkey@0,js_index@0,js_banner_ctrl@0,js_inputlog@0,js_bdnow@0,js_nctips@0,js_widget_textinput@0,js_widget_sug@0,js_mp@0,js_hash_lib@0,js_skinRenderIndex@0,js_skinIphone@0,js_prefetch@0,js_sug@0,js_iscroll@0,js_superframe@0,js_init@0,js_geolocation@0,js_login@0,js_tab@0,js_md5@0,js_url@0,js_lswrite@0,js_modal@0,js_thirdparty@0,js_m_monitor@0,js_superstart@0,js_baiduloc@0,js_callbaiduapp_android@0&callback=B.getCode&r=248&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085","startTime":617.3689999850467,"endTime":849.1769999964163,"transferSize":154395,"resourceSize":457993,"statusCode":200,"mimeType":"text/javascript","resourceType":"Script"},{"url":"https://m.baidu.com/se/static/img/iphone/logo.png","startTime":617.9009999614209,"endTime":717.0029999688268,"transferSize":14253,"resourceSize":13750,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/img/iphone/tab_loading__bg_logo.png","startTime":618.1399999768473,"endTime":697.9949999949895,"transferSize":8716,"resourceSize":8214,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/static/search/clear.png","startTime":933.5490000084974,"endTime":960.9829999972135,"transferSize":1055,"resourceSize":587,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/ralltiir_489d038.js","startTime":938.4399999980815,"endTime":954.9879999831319,"transferSize":11414,"resourceSize":37447,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://m.baidu.com/sugrec?type=3&prod=his&pic=1&from=wise_web&lid=2346015140&ishome=1&net=1&islogin=0&hissid=114551,143669,142112,140843,142507,143382,142210,143859,143879,139043,143162,143867,143424,142580,139178,143344,142779,131246,142909,137743,138165,141942,127969,142871,140066,142906,140593,143058,141807,138425,143469,143923,131423,144005,144087,138595,139883,143477,140312,138661,141103,110085&lid=2346015140&_=1585042746847","startTime":948.8589999964461,"endTime":983.323999971617,"transferSize":1315,"resourceSize":935,"statusCode":200,"mimeType":"text/plain","resourceType":"XHR"},{"url":"https://feed.baidu.com/feed/api/tab/gettabinfo?pd=wise&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&ssid=0&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&qid=2346015140&ms=1&cb=indJsonp&current_data=%22%22&_=1585042746857&cb=jsonp1","startTime":958.6089999647811,"endTime":1092.5099999876693,"transferSize":3254,"resourceSize":2886,"statusCode":200,"mimeType":"text/html","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/package/newsActivity_20ba6a6.js","startTime":966.7979999794625,"endTime":992.337999981828,"transferSize":33335,"resourceSize":107774,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://s.bdstatic.com/common/openjs/openBox.js?_v=2020-03-24-17","startTime":970.9509999956936,"endTime":1010.8269999618642,"transferSize":12485,"resourceSize":31915,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042746817&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=index","startTime":974.1780000040308,"endTime":1009.840999962762,"transferSize":441,"resourceSize":0,"statusCode":200,"mimeType":"text/plain","resourceType":"Image"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js","startTime":984.3070000060834,"endTime":1007.1729999617673,"transferSize":451,"resourceSize":247,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/underscore_23fe246.js","startTime":984.4939999748021,"endTime":1012.6839999575168,"transferSize":2006,"resourceSize":4609,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/channelMgr/index_c70dc69.js","startTime":1002.7309999568388,"endTime":1044.4949999800883,"transferSize":2373,"resourceSize":5405,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/atomWrapper_6fc442d.js","startTime":1005.5399999837391,"endTime":1027.1869999705814,"transferSize":22215,"resourceSize":59197,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/pack_bc18b69.js","startTime":1005.9999999939464,"endTime":1039.7130000055768,"transferSize":4036,"resourceSize":10048,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/package/superframe_5b7bdae.js","startTime":1010.3709999821149,"endTime":1029.9789999844506,"transferSize":3013,"resourceSize":7744,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://hm.baidu.com/hm.js?12423ecbc0e2ca965d84259063d35238","startTime":1013.0720000015572,"endTime":1151.7239999957383,"transferSize":13990,"resourceSize":38392,"statusCode":200,"mimeType":"application/javascript","resourceType":"Script"},{"url":"http://127.0.0.1:59468/?data=fCMxIzsjMi8xLzUjLSMyIzsjbVRmW1ZlT3daWElUN1cyZFQzNm15VHZ5Y3k3dGhCentWOm1HMXRNa1lXaVZTdmpuOlFpczVvNEVGNVosS1JLd1VnW3l2eFpFQ3lbbzlmNk1Na3A6Y0I%2BPiMtIzMjOyM5NTVjfSMtIzQjOzI2OTYxNTM4NTc6MjF%2B","startTime":1013.8099999749102,"endTime":3018.5319999582134,"transferSize":0,"resourceSize":0,"statusCode":-1,"mimeType":"","resourceType":"Image"},{"url":"https://s.bdstatic.com/common/openjs/amd/eslx.js","startTime":1027.9549999977462,"endTime":1042.3089999821968,"transferSize":3994,"resourceSize":8143,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sv.bdstatic.com/static/fecommon/growth/release/core.js?_sv=2020032417","startTime":1028.4179999725893,"endTime":1046.3630000012927,"transferSize":25315,"resourceSize":106254,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://ext.baidu.com/rest/id-mapping/cuid?callback=_box_jsonp932","startTime":1035.801999969408,"endTime":1142.1320000081323,"transferSize":602,"resourceSize":109,"statusCode":200,"mimeType":"application/json","resourceType":"Script"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/default_icon_02f13d8.png","startTime":1055.6029999861494,"endTime":1114.3370000063442,"transferSize":24844,"resourceSize":24341,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/hanbaobao_04adf60.png","startTime":1070.0859999633394,"endTime":1100.2989999833517,"transferSize":711,"resourceSize":212,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/guanzhu_0edf6fe.png","startTime":1070.3900000080466,"endTime":1097.1370000042953,"transferSize":2222,"resourceSize":1721,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/shoucang_5ef89d6.png","startTime":1070.6439999630675,"endTime":1098.8179999985732,"transferSize":2875,"resourceSize":2374,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/dingdan_6391122.png","startTime":1071.0160000016913,"endTime":1101.3589999638498,"transferSize":835,"resourceSize":335,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/pifu_eef387c.png","startTime":1071.4529999531806,"endTime":1121.979999996256,"transferSize":2029,"resourceSize":1528,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/fankui_cc44349.png","startTime":1097.433999995701,"endTime":1126.5300000086427,"transferSize":3185,"resourceSize":2684,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/spritelist_71904c7.png","startTime":1099.1069999872707,"endTime":1153.121999988798,"transferSize":28854,"resourceSize":28351,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://feed.baidu.com/feed/api/wise/feedlist?sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&ssid=0&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&qid=2346015140&clickDownload=0&tabId=1&sync=1&_=1585042747008&callback=jsonp2","startTime":1109.3509999918751,"endTime":1364.3869999796152,"transferSize":29451,"resourceSize":131434,"statusCode":200,"mimeType":"application/json","resourceType":"Script"},{"url":"","startTime":1109.87699998077,"endTime":1109.9149999790825,"transferSize":0,"resourceSize":148,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://m.baidu.com/static/index/plus/public/tab_news.png","startTime":1110.4209999903105,"endTime":1138.1469999905676,"transferSize":2728,"resourceSize":2259,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://hm.baidu.com/hm.gif?cc=1&ck=1&cl=24-bit&ds=412x660&vl=660&et=0&ja=0&ln=zh-cn&lo=0&rnd=1423103317&si=12423ecbc0e2ca965d84259063d35238&v=1.2.68&lv=1&sn=13237&ct=!!&tt=%E7%99%BE%E5%BA%A6%E4%B8%80%E4%B8%8B","startTime":1161.9829999981448,"endTime":1199.5170000009239,"transferSize":299,"resourceSize":43,"statusCode":200,"mimeType":"image/gif","resourceType":"Image"},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/BdrainswDislike/dist/index_f95793e.js","startTime":1382.439000008162,"endTime":1404.404999979306,"transferSize":3055,"resourceSize":6799,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://ss0.bdstatic.com/9bA1vGfa2gU2pMbfm9GUKT-w/timg?searchbox_feed&size=f218_146&quality=80&wh_rate=0&imgtype=0&ref=http%3A%2F%2Fwww.baidu.com&sec=0&di=12061d17028afa425d23780b40b0d708&src=http%3A%2F%2Fpic.rmb.bdstatic.com%2Ff1cdf0359d86d51c3331cde3723118b5.jpeg","startTime":1412.0750000001863,"endTime":1573.8910000072792,"transferSize":5561,"resourceSize":5090,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3318486632,1339666056&fm=173&app=49&f=JPEG?w=312&h=208&s=1A11408196234911188845F203009032","startTime":1412.4040000024252,"endTime":1471.6609999886714,"transferSize":12083,"resourceSize":11737,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3800483417,844282883&fm=173&app=49&f=JPEG?w=312&h=208&s=5704D6AB68638EDE1859FDA303007003","startTime":1413.0069999955595,"endTime":1479.4380000093952,"transferSize":22257,"resourceSize":21903,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2632279595,1216295494&fm=173&app=49&f=JPEG?w=312&h=208&s=FD541DC7085228D0480655320300D019","startTime":1413.6479999870062,"endTime":1483.3679999574088,"transferSize":18130,"resourceSize":17774,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss0.bdstatic.com/9bA1vGfa2gU2pMbfm9GUKT-w/timg?searchbox_feed&size=f218_146&quality=80&wh_rate=0&imgtype=0&ref=http%3A%2F%2Fwww.baidu.com&sec=0&di=df1b88d6f418cc80ff3c4697022c41e2&src=http%3A%2F%2Fpic.rmb.bdstatic.com%2F5b76998f481b4560f0095cea642fdc1f.jpeg","startTime":1414.0739999711514,"endTime":1573.6899999901652,"transferSize":3443,"resourceSize":2974,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2658358766,1284770639&fm=173&app=49&f=JPEG?w=312&h=208&s=B9BC7F9598D052C429B514370300C060","startTime":1414.4159999559633,"endTime":1485.7919999631122,"transferSize":17312,"resourceSize":16959,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1937580919,1810285304&fm=173&app=49&f=JPEG?w=312&h=208&s=B03B5F95F20B6F4D70A1146D0300D073","startTime":1416.2800000049174,"endTime":1476.8909999984317,"transferSize":14201,"resourceSize":13852,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2629148719,529282553&fm=173&app=49&f=JPEG?w=312&h=208&s=2E809C4DDE03454D1F31217A0300805A","startTime":1416.7639999650419,"endTime":1479.6639999840409,"transferSize":14275,"resourceSize":13931,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/newtab/img/fetch_ing_8_0.png","startTime":1417.5650000106543,"endTime":1435.6879999977536,"transferSize":1190,"resourceSize":917,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"","startTime":1427.525999955833,"endTime":1427.6170000084676,"transferSize":0,"resourceSize":298,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"","startTime":1428.1740000005811,"endTime":1428.2339999917895,"transferSize":0,"resourceSize":397,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/report.png","startTime":1430.817999993451,"endTime":1459.499999997206,"transferSize":1782,"resourceSize":1346,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/base/uilib/iconfont/iconfont_fcd5aba.woff?","startTime":1498.6279999720864,"endTime":1537.276999966707,"transferSize":29718,"resourceSize":29444,"statusCode":200,"mimeType":"application/octet-stream","resourceType":"Font"},{"url":"https://hpd.baidu.com/v.gif?logid=2346015140&ssid=0&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=1&cst=1&logFrom=mid_news&logInfo=a2_l*&logExtra=%7B%22st%22%3A%22news%22%2C%22rid%22%3A%229275447518675333919%22%2C%22isBaijiahao%22%3A1%2C%22extra%22%3A%22%7B%5C%22rec_src%5C%22%3A%5B52%5D%2C%5C%22mark%5C%22%3A0%2C%5C%22mark_rec%5C%22%3A0%2C%5C%22round_loop_ids%5C%22%3A%5B100%2C200%5D%2C%5C%22top%5C%22%3A1%2C%5C%22ua%5C%22%3A%5C%220_0__0_240%5C%22%2C%5C%22ut%5C%22%3A%5C%22%5C%22%2C%5C%22province%5C%22%3A%5C%22%5C%5Cu6e56%5C%5Cu5317%5C%22%2C%5C%22city%5C%22%3A%5C%22%5C%5Cu9ec4%5C%5Cu5188%5C%22%2C%5C%22district%5C%22%3A%5C%22%5C%22%2C%5C%22channel_id%5C%22%3A1%2C%5C%22session_id%5C%22%3A%5C%2215850427466914%5C%22%2C%5C%22refresh_index%5C%22%3A%5C%22%5C%22%2C%5C%22position%5C%22%3A0%2C%5C%22log_id%5C%22%3A2346735357%2C%5C%22refresh_state%5C%22%3A1%2C%5C%22city_code%5C%22%3A%5C%22271%5C%22%2C%5C%22local_city%5C%22%3A-1%2C%5C%22user_type%5C%22%3A1%2C%5C%22refresh_type%5C%22%3A1%2C%5C%22refresh_timestamp_ms%5C%22%3A1585042746766%2C%5C%22cs%5C%22%3A%5C%22906297783%20497651126%5C%22%2C%5C%22gr_policy_flag%5C%22%3A0%2C%5C%22final_score%5C%22%3A3%2C%5C%22author_authority_score_v1%5C%22%3A2%2C%5C%22audit_final_score%5C%22%3A3%2C%5C%22predictor_q_score%5C%22%3A0%2C%5C%22vertical_types%5C%22%3A%5B0%2C26%5D%2C%5C%22templates%5C%22%3A%7B%5C%22id%5C%22%3A%5B30%2C30%5D%7D%2C%5C%22wifiinfo%5C%22%3A%5C%22%5C%22%2C%5C%22gr_original_pos%5C%22%3A0%2C%5C%22gr_step_click%5C%22%3A0.0091728856787086%2C%5C%22gr_step_related_click%5C%22%3A6.8901966187696e-5%2C%5C%22dispatch_time%5C%22%3A1585042746%2C%5C%22msrcid%5C%22%3A80001%2C%5C%22mthid%5C%22%3A%5C%221587267721576374%5C%22%2C%5C%22mrtype%5C%22%3A%5C%22text%5C%22%7D%22%2C%22title%22%3A%22%E4%B8%80%E5%A4%A93%E6%AC%A1%E9%80%9A%E8%AF%9D%EF%BC%8C%E4%B9%A0%E4%B8%BB%E5%B8%AD%E5%AF%86%E9%9B%86%E5%8F%91%E5%87%BA%E5%9B%A2%E7%BB%93%E5%90%88%E4%BD%9C%E7%9A%84%E4%B8%AD%E5%9B%BD%E5%80%A1%E8%AE%AE%22%2C%22picNum%22%3A0%2C%22stype%22%3A0%2C%22itemType%22%3A%22newsTitle%22%2C%22pos%22%3A1%7D%2C%7B%22st%22%3A%22news%22%2C%22rid%22%3A%229069318972944726870%22%2C%22isBaijiahao%22%3A1%2C%22extra%22%3A%22%7B%5C%22rec_src%5C%22%3A%5B999%5D%2C%5C%22type%5C%22%3A0%2C%5C%22mark%5C%22%3A0%2C%5C%22attentionnum%5C%22%3A0%2C%5C%22th%5C%22%3A-1%2C%5C%22ua%5C%22%3A%5C%220_0__0_240%5C%22%2C%5C%22ut%5C%22%3A%5C%22%5C%22%2C%5C%22province%5C%22%3A%5C%22%5C%5Cu6e56%5C%5Cu5317%5C%22%2C%5C%22city%5C%22%3A%5C%22%5C%5Cu9ec4%5C%5Cu5188%5C%22%2C%5C%22district%5C%22%3A%5C%22%5C%22%2C%5C%22channel_id%5C%22%3A1%2C%5C%22round_loop_ids%5C%22%3A%5B200%5D%2C%5C%22session_id%5C%22%3A%5C%2215850427466914%5C%22%2C%5C%22refresh_index%5C%22%3A%5C%22%5C%22%2C%5C%22position%5C%22%3A1%2C%5C%22log_id%5C%22%3A2346735357%2C%5C%22refresh_state%5C%22%3A1%2C%5C%22city_code%5C%22%3A%5C%22271%5C%22%2C%5C%22local_city%5C%22%3A-1%2C%5C%22user_type%5C%22%3A1%2C%5C%22refresh_type%5C%22%3A1%2C%5C%22refresh_timestamp_ms%5C%22%3A1585042746766%2C%5C%22cs%5C%22%3A%5C%223966240335%201299908375%5C%22%2C%5C%22gr_policy_flag%5C%22%3A0%2C%5C%22final_score%5C%22%3A2%2C%5C%22author_authority_score_v1%5C%22%3A4%2C%5C%22audit_final_score%5C%22%3A3%2C%5C%22news_style_super%5C%22%3A%5C%22%5C%5Cu8d1f%5C%5Cu9762%2C%5C%5Cu753b%5C%5Cu98ce%5C%5Cu7c97%5C%5Cu52a3%5C%22%2C%5C%22predictor_q_score%5C%22%3A0%2C%5C%22vertical_types%5C%22%3A%5B0%2C26%5D%2C%5C%22templates%5C%22%3A%7B%5C%22id%5C%22%3A%5B30%5D%7D%2C%5C%22wifiinfo%5C%22%3A%5C%22%5C%22%2C%5C%22gr_original_pos%5C%22%3A1%2C%5C%22gr_step_click%5C%22%3A0.045161370187998%2C%5C%22gr_step_related_click%5C%22%3A0.00010657673283276%2C%5C%22overwrite%5C%22%3A1%2C%5C%22dispatch_time%5C%22%3A1585042746%2C%5C%22msrcid%5C%22%3A80001%2C%5C%22mthid%5C%22%3A%5C%221552864910655429%5C%22%2C%5C%22mrtype%5C%22%3A%5C%22text%5C%22%7D%22%2C%22title%22%3A%22%E5%85%A8%E7%90%83%E6%96%B0%E5%86%A0%E8%82%BA%E7%82%8E%E7%A1%AE%E8%AF%8A%E7%97%85%E4%BE%8B%E8%B6%85%E8%BF%8738%E4%B8%87%E4%BE%8B%20%E7%BE%8E%E5%9B%BD%E8%B6%854.6%E4%B8%87%E4%BE%8B%22%2C%22picNum%22%3A0%2C%22stype%22%3A0%2C%22isbdopen%22%3A1%2C%22itemType%22%3A%22newsTitle%22%2C%22pos%22%3A2%2C%22xsourceTag%22%3Atrue%7D&tid=2066&r=l1585042748114","startTime":2216.3019999861717,"endTime":2259.3379999743775,"transferSize":130,"resourceSize":0,"statusCode":200,"mimeType":"image/gif","resourceType":"Image"},{"url":"https://hm.baidu.com/hm.gif?si=c42dc7b5fa22eba9c22b2ca4d8829372&et=0&v=pixel-1.0&u=https%3A%2F%2Fm.baidu.com%2Fexp%2Ffailed%3Fv%3D1.0.4&rnd=1000051735","startTime":3019.970999972429,"endTime":3088.166999979876,"transferSize":299,"resourceSize":43,"statusCode":200,"mimeType":"image/gif","resourceType":"Image"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/bubble/bubble_ba92dca.js","startTime":3091.25800000038,"endTime":3105.2879999624565,"transferSize":540,"resourceSize":394,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/logo/logo_857fccc.js","startTime":3091.677999997046,"endTime":3108.6219999706373,"transferSize":567,"resourceSize":485,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/a4/carousel_408bced.js","startTime":3092.0319999568164,"endTime":3108.3809999981895,"transferSize":2991,"resourceSize":8219,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/plugin/safariicon_6bd009a.js","startTime":3092.4590000067838,"endTime":3112.461999990046,"transferSize":3539,"resourceSize":8542,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/setIvkCK_bb46616.js","startTime":3093.4309999574907,"endTime":3109.1359999845736,"transferSize":364,"resourceSize":97,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/component/background_0a042a0.js","startTime":3094.0800000098534,"endTime":3108.810000005178,"transferSize":544,"resourceSize":400,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/component/btmBanner_f91323e.js","startTime":3094.3509999779053,"endTime":3111.797999998089,"transferSize":5140,"resourceSize":7529,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/component/fullscreen_f01324e.js","startTime":3094.695999985561,"endTime":3112.1189999976195,"transferSize":1498,"resourceSize":2332,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/ivkBox_2c53958.js","startTime":3108.104999992065,"endTime":3123.4809999587014,"transferSize":1031,"resourceSize":1388,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/getInvokeLogData_fc32168.js","startTime":3114.049999974668,"endTime":3133.574999985285,"transferSize":515,"resourceSize":330,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/serverDataFactory_568f951.js","startTime":3115.474999998696,"endTime":3132.4799999711104,"transferSize":860,"resourceSize":1149,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/fnProvider_9833c78.js","startTime":3116.0739999613725,"endTime":3132.276999996975,"transferSize":1497,"resourceSize":2766,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/Core_426be15.js","startTime":3117.716999957338,"endTime":3134.533000004012,"transferSize":1186,"resourceSize":2273,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/Carousel_76e2bc0.js","startTime":3118.183999962639,"endTime":3134.2379999696277,"transferSize":2605,"resourceSize":6913,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/bannerConfig_9ec6e61.js","startTime":3118.625000002794,"endTime":3133.8509999914095,"transferSize":621,"resourceSize":555,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/invokeCookie_2b36f0c.js","startTime":3120.002999959979,"endTime":3136.3559999736026,"transferSize":993,"resourceSize":1299,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/log_8406fdd.js","startTime":3123.1259999913163,"endTime":3138.3679999853484,"transferSize":649,"resourceSize":648,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/setFullScreenIvkCK_92b17a0.js","startTime":3124.022000003606,"endTime":3138.6809999821708,"transferSize":892,"resourceSize":1112,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/invoke-box_3f05010.js","startTime":3128.411999961827,"endTime":3143.355000007432,"transferSize":12149,"resourceSize":35788,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/invokeBox_12354c1.js","startTime":3139.288000005763,"endTime":3152.5369999581017,"transferSize":969,"resourceSize":1381,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/invokeSecr_13c5fec.js","startTime":3139.6700000041164,"endTime":3152.8699999907985,"transferSize":2238,"resourceSize":4297,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/DataProcess_deb477f.js","startTime":3145.638999994844,"endTime":3160.7460000086576,"transferSize":664,"resourceSize":831,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/StrategyDataProcess_787f12d.js","startTime":3145.98799997475,"endTime":3161.3629999919794,"transferSize":715,"resourceSize":746,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/ShieldMonitor_b61052e.js","startTime":3146.7479999992065,"endTime":3161.0689999652095,"transferSize":1079,"resourceSize":1675,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/wise-invoke-popup_fa02b72.js","startTime":3158.021999988705,"endTime":3172.393999993801,"transferSize":1486,"resourceSize":3058,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/user-agent_24ce52d.js","startTime":3158.572999993339,"endTime":3173.979999963194,"transferSize":1131,"resourceSize":2631,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/get-app-info_2747ad8.js","startTime":3160.3359999717213,"endTime":3174.8619999852963,"transferSize":451,"resourceSize":316,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749078&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=2&ref=index_iphone&logFrom=callbaidu&logInfo=defaul_try","startTime":3182.226000004448,"endTime":3219.368999998551,"transferSize":347,"resourceSize":0,"statusCode":200,"mimeType":"text/plain","resourceType":"Image"},{"url":"https://m.baidu.com/tcbox?service=bdbox&action=pblog&ctv=2&cen=uid_ua_ut&data=%7B%22appid%22%3A%221%22%2C%22dataid%22%3A%222%22%2C%22actiontype%22%3A%221%22%2C%22actionid%22%3A%222%22%2C%22actiondata%22%3A%7B%22ref%22%3A%22%22%2C%22gmv%22%3A%22%22%2C%22source%22%3A%22%22%2C%22boxVersion%22%3A0%2C%22boxPlatform%22%3A%22android%22%2C%22evtName%22%3A%22openBox%22%2C%22evtType%22%3A%221021206d%22%2C%22evtTag%22%3A%7B%22source%22%3A%221021206d%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22chrome%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22%22%2C%22channel%22%3A%221021206r%22%2C%22extlog%22%3A%22%22%2C%22baiduId%22%3A%2288C7BD6C60D47AD71CFBE516CB4A166B%3AFG%3D1%22%2C%22app_now%22%3A%22chrome_1585042749079_3561962775%22%2C%22yyb_pkg%22%3A%22com.baidu.searchbox%22%2C%22idmData%22%3A%7B%22firstOpen%22%3A%22lite%22%2C%22secondOpen%22%3A%22main%22%2C%22status%22%3A%220%22%2C%22timeout%22%3A1585129147042%7D%2C%22matrix%22%3A%22lite%22%7D%7D%2C%22cateid%22%3A14%7D&_rnd=1790118702","startTime":3182.42599995574,"endTime":3218.3619999559596,"transferSize":0,"resourceSize":0,"statusCode":200,"mimeType":"text/html","resourceType":"Image"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/jssdk_6c0ef3a.js","startTime":3185.0090000079945,"endTime":3197.413999994751,"transferSize":553,"resourceSize":504,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/promise_ac4cb03.js","startTime":3199.900000006892,"endTime":3217.570999986492,"transferSize":1597,"resourceSize":3742,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/Boxjs-search_2ce639b.js","startTime":3200.2779999747872,"endTime":3216.8949999613687,"transferSize":5584,"resourceSize":22673,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"baiduboxlite://utils?action=sendIntent&minver=3.3&params=%7B%22intent%22%3A%22intent%3A%23Intent%3Baction%3Dcom.baidu.searchbox.action.HOME%3Bpackage%3Dcom.baidu.searchbox.lite%3BS.targetCommand%3D%257B%2522mode%2522%253A%25220%2522%252C%2522intent%2522%253A%2522intent%253A%2523Intent%253Baction%253Dcom.baidu.searchbox.action.HOME%253Bcategory%253Dandroid.intent.category.DEFAULT%253BS.extra_target_tab%253DFeed%253Bend%2522%252C%2522min_v%2522%253A%252220120832%2522%257D%3Bend%22%7D&needlog=1&logargs=%7B%22source%22%3A%221021206d%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22chrome%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22%22%2C%22channel%22%3A%221021206r%22%2C%22extlog%22%3A%22%22%2C%22baiduId%22%3A%2288C7BD6C60D47AD71CFBE516CB4A166B%3AFG%3D1%22%2C%22app_now%22%3A%22chrome_1585042749079_3561962775%22%2C%22yyb_pkg%22%3A%22com.baidu.searchbox%22%2C%22idmData%22%3A%7B%22firstOpen%22%3A%22lite%22%2C%22secondOpen%22%3A%22main%22%2C%22status%22%3A%220%22%2C%22timeout%22%3A1585129147042%7D%2C%22matrix%22%3A%22lite%22%7D","startTime":3221.360999974422,"endTime":3222.0070000039414,"transferSize":0,"resourceSize":0,"statusCode":-1,"mimeType":"","resourceType":"Document"},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/Boxjs-amd_1cd9b4a.js","startTime":3224.2850000038743,"endTime":3242.510999960359,"transferSize":7957,"resourceSize":28020,"statusCode":200,"mimeType":"application/x-javascript","resourceType":"Script"},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/img/baiduappAdCloseWhite_b84ffa8.png","startTime":3250.727000006009,"endTime":3264.590999984648,"transferSize":1917,"resourceSize":1634,"statusCode":200,"mimeType":"image/png","resourceType":"Image"},{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/duobao.jpg","startTime":3251.0809999657795,"endTime":3290.1529999799095,"transferSize":163741,"resourceSize":163096,"statusCode":200,"mimeType":"image/jpeg","resourceType":"Image"},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749147&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=baidulogo&logoInfo=%7B%22origin%22%3A%221023197w%22%2C%22from%22%3A%22844b%22%2C%22channel%22%3A%221023206g%22%2C%22browserid%22%3A%2224%22%2C%22qid%22%3A%222346015140%22%2C%22timestamp%22%3A1585042749146%7D","startTime":3252.995999995619,"endTime":3292.8630000096746,"transferSize":347,"resourceSize":0,"statusCode":200,"mimeType":"text/plain","resourceType":"Image"},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749152&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=A4&logInfo=%7B%22origin%22%3A%221023857w%22%2C%22from%22%3A%22844b%22%2C%22channel%22%3A%221023864w%22%2C%22browserid%22%3A%2224%22%2C%22qid%22%3A%222346015140%22%2C%22timestamp%22%3A1585042749149%2C%22experiment%22%3A%22single%22%2C%22action%22%3A%22show%22%7D","startTime":3253.255999996327,"endTime":3291.21799999848,"transferSize":347,"resourceSize":0,"statusCode":200,"mimeType":"text/plain","resourceType":"Image"},{"url":"baiduboxapp://utils?action=sendIntent&minver=7.4&params=%7B%22intent%22%3A%22intent%3A%23Intent%3Baction%3Dcom.baidu.searchbox.action.HOME%3Bpackage%3Dcom.baidu.searchbox%3BS.targetCommand%3D%257B%2522mode%2522%253A%25220%2522%252C%2522intent%2522%253A%2522intent%253A%2523Intent%253Baction%253Dcom.baidu.searchbox.action.HOME%253Bcategory%253Dandroid.intent.category.DEFAULT%253BS.extra_target_tab%253DFeed%253Bend%2522%252C%2522min_v%2522%253A%252216787968%2522%257D%3Bend%22%7D&needlog=1&logargs=%7B%22source%22%3A%221021206d%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22chrome%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22%22%2C%22channel%22%3A%221021206r%22%2C%22extlog%22%3A%22%22%2C%22baiduId%22%3A%2288C7BD6C60D47AD71CFBE516CB4A166B%3AFG%3D1%22%2C%22app_now%22%3A%22chrome_1585042749222_5861823275%22%2C%22yyb_pkg%22%3A%22com.baidu.searchbox%22%2C%22idmData%22%3A%7B%22firstOpen%22%3A%22lite%22%2C%22secondOpen%22%3A%22main%22%2C%22status%22%3A%220%22%2C%22timeout%22%3A1585129147042%7D%2C%22matrix%22%3A%22main%22%7D","startTime":3323.5679999925196,"endTime":3324.1379999672063,"transferSize":0,"resourceSize":0,"statusCode":-1,"mimeType":"","resourceType":"Document"},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749953&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=callbaidush&logInfo=%7B%22pos%22%3A3%2C%22browserid%22%3A%2224%22%2C%22from%22%3A%22844b%22%2C%22channel%22%3A%221023864w%22%2C%22source%22%3A%221023857w%22%2C%22show%22%3A1%7D","startTime":4054.589999956079,"endTime":4093.7639999901876,"transferSize":347,"resourceSize":0,"statusCode":200,"mimeType":"text/plain","resourceType":"Image"}]}},"network-rtt":{"id":"network-rtt","title":"网络往返时间","description":"网络往返时间 (RTT) 对性能有很大的影响。如果与来源之间的 RTT 较长，则表明缩短服务器与用户之间的距离可能会提高性能。[了解详情](https://hpbn.co/primer-on-latency-and-bandwidth/)。","score":null,"scoreDisplayMode":"informative","numericValue":30.134,"displayValue":"30 毫秒","details":{"type":"table","headings":[{"key":"origin","itemType":"text","text":"网址"},{"key":"rtt","itemType":"ms","granularity":1,"text":"花费的时间"}],"items":[{"origin":"https://hm.baidu.com","rtt":30.134},{"origin":"https://feed.baidu.com","rtt":24.93},{"origin":"https://www.baidu.com","rtt":24.137999999999998},{"origin":"https://m.baidu.com","rtt":20.596},{"origin":"https://hpd.baidu.com","rtt":20.555000000000007},{"origin":"https://ext.baidu.com","rtt":20.087},{"origin":"https://ss1.baidu.com","rtt":12.859000000000002},{"origin":"https://ss2.baidu.com","rtt":11.115},{"origin":"https://imgsa.baidu.com","rtt":10.187},{"origin":"https://gss0.bdstatic.com","rtt":9.951},{"origin":"https://ss0.bdstatic.com","rtt":9.731999999999985},{"origin":"https://sm.bdimg.com","rtt":9.559},{"origin":"https://s.bdstatic.com","rtt":9.071000000000002},{"origin":"https://sv.bdstatic.com","rtt":9.071000000000002},{"origin":"https://b.bdstatic.com","rtt":9.071000000000002}]}},"network-server-latency":{"id":"network-server-latency","title":"服务器后端延迟","description":"服务器延迟时间可能会对网站性能产生不良影响。如果源服务器的延迟时间较长，则表明服务器过载或后端性能较差。[了解详情](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)。","score":null,"scoreDisplayMode":"informative","numericValue":75.54599999999999,"displayValue":"80 毫秒","details":{"type":"table","headings":[{"key":"origin","itemType":"text","text":"网址"},{"key":"serverResponseTime","itemType":"ms","granularity":1,"text":"花费的时间"}],"items":[{"origin":"https://www.baidu.com","serverResponseTime":75.54599999999999},{"origin":"https://ext.baidu.com","serverResponseTime":39.494},{"origin":"https://hpd.baidu.com","serverResponseTime":13.472000000000008},{"origin":"https://ss2.baidu.com","serverResponseTime":9.29499999999999},{"origin":"https://b.bdstatic.com","serverResponseTime":9.236999999999998},{"origin":"https://feed.baidu.com","serverResponseTime":8.901999999999994},{"origin":"https://hm.baidu.com","serverResponseTime":7.344999999999999},{"origin":"https://m.baidu.com","serverResponseTime":6.386000000000006},{"origin":"https://sv.bdstatic.com","serverResponseTime":5.257999999999999},{"origin":"https://ss1.baidu.com","serverResponseTime":5.180999999999997},{"origin":"https://gss0.bdstatic.com","serverResponseTime":4.526999999999999},{"origin":"https://sm.bdimg.com","serverResponseTime":4.116000000000001},{"origin":"https://ss0.bdstatic.com","serverResponseTime":2.390000000000029},{"origin":"https://s.bdstatic.com","serverResponseTime":2.042},{"origin":"https://imgsa.baidu.com","serverResponseTime":1.7630000000000035}]}},"main-thread-tasks":{"id":"main-thread-tasks","title":"Tasks","description":"Lists the toplevel main thread tasks that executed during page load.","score":null,"scoreDisplayMode":"informative","numericValue":20,"details":{"type":"table","headings":[{"key":"startTime","itemType":"ms","granularity":1,"text":"Start Time"},{"key":"duration","itemType":"ms","granularity":1,"text":"End Time"}],"items":[{"duration":12.089,"startTime":507.05},{"duration":7.132,"startTime":537.866},{"duration":59.572,"startTime":545.145},{"duration":6.202,"startTime":615.516},{"duration":20.523,"startTime":627.18},{"duration":123.275,"startTime":859.1},{"duration":5.008,"startTime":988.293},{"duration":18.7,"startTime":1004.625},{"duration":12.084,"startTime":1027.138},{"duration":12.051,"startTime":1053.157},{"duration":11.055,"startTime":1077.298},{"duration":20.018,"startTime":1100.981},{"duration":9.362,"startTime":1160.432},{"duration":54.587,"startTime":1373.189},{"duration":76.085,"startTime":1427.838},{"duration":9.949,"startTime":1511.728},{"duration":13.858,"startTime":1546.248},{"duration":5.298,"startTime":2218.991},{"duration":7.468,"startTime":3183.698},{"duration":15.296,"startTime":3251.032}]}},"metrics":{"id":"metrics","title":"Metrics","description":"Collects all available metrics.","score":null,"scoreDisplayMode":"informative","numericValue":6774.141,"details":{"type":"debugdata","items":[{"firstContentfulPaint":1485,"firstMeaningfulPaint":3474,"firstCPUIdle":5617,"interactive":6774,"speedIndex":4869,"estimatedInputLatency":34,"totalBlockingTime":396,"observedNavigationStart":0,"observedNavigationStartTs":370270184970,"observedFirstPaint":604,"observedFirstPaintTs":370270789014,"observedFirstContentfulPaint":604,"observedFirstContentfulPaintTs":370270789014,"observedFirstMeaningfulPaint":1522,"observedFirstMeaningfulPaintTs":370271707087,"observedLargestContentfulPaint":3314,"observedLargestContentfulPaintTs":370273498587,"observedTraceEnd":4156,"observedTraceEndTs":370274341344,"observedLoad":3091,"observedLoadTs":370273275557,"observedDomContentLoaded":614,"observedDomContentLoadedTs":370270798559,"observedFirstVisualChange":603,"observedFirstVisualChangeTs":370270787970,"observedLastVisualChange":3320,"observedLastVisualChangeTs":370273504970,"observedSpeedIndex":2032,"observedSpeedIndexTs":370272217019},{"lcpInvalidated":false}]}},"offline-start-url":{"id":"offline-start-url","title":"`start_url` 在离线时没有响应，并返回 200","description":"Service Worker 可让您的 Web 应用在无法预测的网络状况下正常运行。[了解详情](https://web.dev/offline-start-url)。","score":0,"scoreDisplayMode":"binary","explanation":"No usable web app manifest found on page.","warnings":[]},"performance-budget":{"id":"performance-budget","title":"性能预算","description":"请将网络请求的数量和数据大小保持在提供的性能预算所设定的目标之内。[了解详情](https://developers.google.com/web/tools/lighthouse/audits/budgets)。","score":null,"scoreDisplayMode":"notApplicable"},"resource-summary":{"id":"resource-summary","title":"请保持较低的请求数量和较小的传输大小","description":"若要设置页面资源数量和大小的预算，请添加 budget.json 文件。[了解详情](https://developers.google.com/web/tools/lighthouse/audits/budgets)。","score":null,"scoreDisplayMode":"informative","displayValue":"99 项请求 • 952 KB","details":{"type":"table","headings":[{"key":"label","itemType":"text","text":"资源类型"},{"key":"requestCount","itemType":"numeric","text":"请求"},{"key":"size","itemType":"bytes","text":"传输文件大小"}],"items":[{"resourceType":"total","label":"总计","requestCount":99,"size":974958},{"resourceType":"image","label":"图片","requestCount":45,"size":421843},{"resourceType":"script","label":"脚本","requestCount":48,"size":387989},{"resourceType":"document","label":"文档","requestCount":3,"size":90780},{"resourceType":"font","label":"字体","requestCount":2,"size":73031},{"resourceType":"other","label":"其他","requestCount":1,"size":1315},{"resourceType":"stylesheet","label":"样式表","requestCount":0,"size":0},{"resourceType":"media","label":"媒体","requestCount":0,"size":0},{"resourceType":"third-party","label":"第三方","requestCount":58,"size":434087}]}},"third-party-summary":{"id":"third-party-summary","title":"第三方使用","description":"第三方代码可能会显著影响加载性能。请限制冗余第三方提供商的数量，并尝试在页面完成主要加载后再加载第三方代码。[了解详情](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)。","score":1,"scoreDisplayMode":"binary","displayValue":"第三方代码将主线程阻止了 50 毫秒","details":{"type":"table","headings":[{"key":"entity","itemType":"link","text":"第三方"},{"key":"transferSize","granularity":1,"itemType":"bytes","text":"大小"},{"key":"blockingTime","granularity":1,"itemType":"ms","text":"主线程拦截时间"}],"items":[{"entity":{"type":"link","text":"Baidu Analytics","url":"https://tongji.baidu.com/web/welcome/login"},"transferSize":540871,"mainThreadTime":634.6119999999992,"blockingTime":48.848}],"summary":{"wastedBytes":540871,"wastedMs":48.848}}},"pwa-cross-browser":{"id":"pwa-cross-browser","title":"网站能在各种浏览器中正常显示","description":"网站应该能在所有主流浏览器中正常显示，以便覆盖数量最多的用户。[了解详情](https://web.dev/pwa-cross-browser)。","score":null,"scoreDisplayMode":"manual"},"pwa-page-transitions":{"id":"pwa-page-transitions","title":"在不同网页之间跳转时，用户感觉不到网页加载缓慢","description":"无论点按哪个链接，都应能快速跳转到相应页面，即使网速缓慢也应如此。若想让用户感知到出色的网页加载速度，这种体验至关重要。[了解详情](https://web.dev/pwa-page-transitions)。","score":null,"scoreDisplayMode":"manual"},"pwa-each-page-has-url":{"id":"pwa-each-page-has-url","title":"每个网页都有一个网址","description":"确保各个网页可通过网址建立深层链接，并且这些网址是独一无二的，可以在社交媒体上共享。[了解详情](https://web.dev/pwa-each-page-has-url)。","score":null,"scoreDisplayMode":"manual"},"accesskeys":{"id":"accesskeys","title":"“`[accesskey]`”值是独一无二的","description":"快捷键可让用户快速转到页面的某个部分。为确保正确进行导航，每个快捷键都必须是独一无二的。[了解详情](https://web.dev/accesskeys/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-allowed-attr":{"id":"aria-allowed-attr","title":"`[aria-*]` 属性与其角色匹配","description":"每个 ARIA“`role`”都支持一部分特定的“`aria-*`”属性。如果这些项不匹配，会导致“`aria-*`”属性无效。[了解详情](https://web.dev/aria-allowed-attr/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-required-attr":{"id":"aria-required-attr","title":"`[role]` 具备所有必需的 `[aria-*]` 属性","description":"一些 ARIA 角色有必需属性，这些属性向屏幕阅读器描述了相应元素的状态。[了解详情](https://web.dev/aria-required-attr/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-required-children":{"id":"aria-required-children","title":"具有 ARIA `[role]`且要求子元素必须包含特定`[role]`的元素包含全部必需子元素。","description":"一些 ARIA 父角色必须包含特定子角色，才能执行它们的预期无障碍功能。[了解详情](https://web.dev/aria-required-children/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-required-parent":{"id":"aria-required-parent","title":"`[role]` 包含在其必需的父元素中","description":"一些 ARIA 子角色必须包含在特定的父角色中，才能正确执行它们的预期无障碍功能。[了解详情](https://web.dev/aria-required-parent/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-roles":{"id":"aria-roles","title":"`[role]` 值有效","description":"ARIA 角色必须具备有效值，才能执行它们的预期无障碍功能。[了解详情](https://web.dev/aria-roles/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-valid-attr-value":{"id":"aria-valid-attr-value","title":"`[aria-*]` 属性具备有效值","description":"辅助技术（如屏幕阅读器）无法解读值无效的 ARIA 属性。[了解详情](https://web.dev/aria-valid-attr-value/)。","score":null,"scoreDisplayMode":"notApplicable"},"aria-valid-attr":{"id":"aria-valid-attr","title":"`[aria-*]` 属性有效且拼写正确","description":"辅助技术（如屏幕阅读器）无法解读名称无效的 ARIA 属性。[了解详情](https://web.dev/aria-valid-attr/)。","score":null,"scoreDisplayMode":"notApplicable"},"audio-caption":{"id":"audio-caption","title":"`\u003caudio>` 元素包含带 `[kind=\"captions\"]` 的 `\u003ctrack>` 元素","description":"字幕让失聪用户或听障用户能够使用音频元素，并可提供关键信息（例如谁在说话、他们在说什么以及其他非语音信息）。[了解详情](https://web.dev/audio-caption/)。","score":null,"scoreDisplayMode":"notApplicable"},"button-name":{"id":"button-name","title":"按钮有可供访问的名称","description":"当某个按钮没有可供访问的名称时，屏幕阅读器会将它读为“按钮”，这会导致依赖屏幕阅读器的用户无法使用它。[了解详情](https://web.dev/button-name/)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"bypass":{"id":"bypass","title":"该页面不含任何标题、跳过链接或地标区域","description":"添加用于绕过重复内容的方式有助于键盘用户更高效地浏览页面。[了解详情](https://web.dev/bypass/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":"html","path":"1,HTML","snippet":"\u003chtml class=\"\">","explanation":"Fix any of the following:\n  No valid skip link found\n  Page does not have a header\n  Page does not have a landmark region","nodeLabel":"html"}}],"debugData":{"type":"debugdata","impact":"serious","tags":["cat.keyboard","wcag2a","wcag241","section508","section508.22.o"]}}},"color-contrast":{"id":"color-contrast","title":"背景色和前景色没有足够高的对比度。","description":"对于许多用户而言，对比度低的文字都是难以阅读或无法阅读的。[了解详情](https://web.dev/color-contrast/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":"#index-bn","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,3,DIV,0,FORM,0,DIV,0,DIV,2,DIV,2,BUTTON","snippet":"\u003cbutton id=\"index-bn\" class=\"se-bn\" type=\"submit\">百度一下\u003c/button>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 3.43 (foreground color: #3388ff, background color: #ffffff, font size: 12.0pt, font weight: bold). Expected contrast ratio of 4.5:1","nodeLabel":"百度一下"}},{"node":{"type":"node","selector":".rn-icon-hot","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,0,DIV,1,DIV,0,A,1,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-icon-hot\">置顶\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 3.84 (foreground color: #ec4345, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"置顶"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 275447518675333919\"] > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,0,DIV,1,DIV,0,A,1,DIV,1,SPAN","snippet":"\u003cspan class=\"rn-domainName\">新华社新媒体\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"新华社新媒体"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 069318972944726870\"] > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,1,DIV,1,DIV,0,A,1,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-domainName\">人民日报海外网\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"人民日报海外网"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 608238416910964472\"] > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,2,DIV,1,DIV,0,A,1,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-domainName\">数字中国\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"数字中国"}},{"node":{"type":"node","selector":"a[data-rid=\"\\31 0260675325280539064\"] > .rn-wise-text-content > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,4,DIV,1,DIV,0,A,1,DIV,1,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-domainName\">音悦梦想达人\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"音悦梦想达人"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 746989792144855077\"] > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,5,DIV,1,DIV,0,A,2,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-domainName\">环京津网\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"环京津网"}},{"node":{"type":"node","selector":"a[data-rid=\"\\31 2209688148686140539\"] > .rn-wise-text-content > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,6,DIV,1,DIV,0,A,1,DIV,1,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-domainName\">电工技能分享\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"电工技能分享"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 545683102936893545\"] > .rn-footer > .rn-domainName","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,7,DIV,1,DIV,0,A,2,DIV,0,SPAN","snippet":"\u003cspan class=\"rn-domainName\">美食杰一食一刻\u003c/span>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.84 (foreground color: #999999, background color: #ffffff, font size: 9.8pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"美食杰一食一刻"}},{"node":{"type":"node","selector":"#index-copyright","path":"1,HTML,2,BODY,3,DIV,0,DIV,8,DIV,0,DIV,1,A","snippet":"\u003ca id=\"index-copyright\" href=\"https://m.baidu.com/sf?pd=sd_privacy_terms&amp;ms=1&amp;ms=1&amp;word=%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E&amp;title=%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E&amp;openapi=1&amp;from_sf=1&amp;resource_id=37483&amp;dsp=iphone&amp;tn=wisexmlnew&amp;ext=%7B%22pid%22%3A%22mianze-shengming%22%7D&amp;lid=&amp;referlid=9224097818218589594&amp;frsrcid=37483&amp;frorder=1\" data-stats=\"10|2|foot|a2_l1\">","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.68 (foreground color: #999999, background color: #f8f8f8, font size: 9.0pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"使用百度前必读 Baidu 京ICP证030173号"}},{"node":{"type":"node","selector":".recordcode","path":"1,HTML,2,BODY,3,DIV,0,DIV,8,DIV,0,DIV,2,A","snippet":"\u003ca class=\"recordcode\" href=\"http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11000002000001\" target=\"_blank\">\u003ci>\u003c/i>京公网安备11000002000001号\u003c/a>","explanation":"Fix any of the following:\n  Element has insufficient color contrast of 2.68 (foreground color: #999999, background color: #f8f8f8, font size: 9.0pt, font weight: normal). Expected contrast ratio of 4.5:1","nodeLabel":"京公网安备11000002000001号"}}],"debugData":{"type":"debugdata","impact":"serious","tags":["cat.color","wcag2aa","wcag143"]}}},"definition-list":{"id":"definition-list","title":"`\u003cdl>` 只包含经过适当排序的 `\u003cdt>` 和 `\u003cdd>` 组及 `\u003cscript>` 或 `\u003ctemplate>` 元素。","description":"如果未正确标记定义列表，屏幕阅读器可能会读出令人困惑或不准确的内容。[了解详情](https://web.dev/definition-list/)。","score":null,"scoreDisplayMode":"notApplicable"},"dlitem":{"id":"dlitem","title":"定义列表项已封装在 `\u003cdl>` 元素中","description":"定义列表项 (`\u003cdt>` 和 `\u003cdd>`) 必须封装在父 `\u003cdl>` 元素中，以确保屏幕阅读器可以正确地读出它们。[了解详情](https://web.dev/dlitem/)。","score":null,"scoreDisplayMode":"notApplicable"},"document-title":{"id":"document-title","title":"文档包含 `\u003ctitle>` 元素","description":"屏幕阅读器用户可借助标题来大致了解某个页面的内容，搜索引擎用户则非常依赖标题来确定某个页面是否与其搜索相关。[了解详情](https://web.dev/document-title/)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"duplicate-id":{"id":"duplicate-id","title":"页面上的 `[id]` 属性是独一无二的","description":"id 属性的值必须独一无二，以防其他实例被辅助技术忽略。[了解详情](https://web.dev/duplicate-id/)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"frame-title":{"id":"frame-title","title":"`\u003cframe>` 或 `\u003ciframe>` 元素有标题","description":"屏幕阅读器用户依靠框架标题来描述框架的内容。[了解详情](https://web.dev/frame-title/)。","score":null,"scoreDisplayMode":"notApplicable"},"html-has-lang":{"id":"html-has-lang","title":"`\u003chtml>` 元素缺少 `[lang]` 属性","description":"如果页面未指定 lang 属性，屏幕阅读器便会假定该页面采用的是用户在设置屏幕阅读器时选择的默认语言。如果该页面实际上并未采用默认语言，则屏幕阅读器可能无法正确读出该页面中的文字。[了解详情](https://web.dev/html-has-lang/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":"html","path":"1,HTML","snippet":"\u003chtml class=\"\">","explanation":"Fix any of the following:\n  The \u003chtml> element does not have a lang attribute","nodeLabel":"html"}}],"debugData":{"type":"debugdata","impact":"serious","tags":["cat.language","wcag2a","wcag311"]}}},"html-lang-valid":{"id":"html-lang-valid","title":"`\u003chtml>` 元素的 `[lang]` 属性具备有效值","description":"指定有效的 [BCP 47 语言](https://www.w3.org/International/questions/qa-choosing-language-tags#question)有助于屏幕阅读器正确读出文字。[了解详情](https://web.dev/html-lang-valid/)。","score":null,"scoreDisplayMode":"notApplicable"},"image-alt":{"id":"image-alt","title":"图片元素缺少 `[alt]` 属性","description":"说明性元素应力求使用简短的描述性替代文字。未指定 alt 属性的装饰性元素可被忽略。[了解详情](https://web.dev/image-alt/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":".index-banner > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,0,DIV,0,DIV,0,A,0,IMG","snippet":"\u003cimg src=\"https://imgsa.baidu.com/normandy/pic/item/35a85edf8db1cb136e736049d254564e92584b55.jpg\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\31 0260675325280539064\"] > .rn-small-video-wrap.rn-video-wrap > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,4,DIV,1,DIV,0,A,0,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss0.bdstatic.com/9bA1vGfa2gU2pMbfm9GUKT-w/timg?searchbox_feed&amp;size=f218_146&amp;quality=80&amp;wh_rate=0&amp;imgtype=0&amp;ref=http%3A%2F%2Fwww.baidu.com&amp;sec=0&amp;di=12061d17028afa425d23780b40b0d708&amp;src=http%3A%2F%2Fpic.rmb.bdstatic.com%2Ff1cdf0359d86d51c3331cde3723118b5.jpeg\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 746989792144855077\"] > .rn-three-pic-content > .rn-three-pic-wrap:nth-child(1) > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,5,DIV,1,DIV,0,A,1,DIV,0,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3318486632,1339666056&amp;fm=173&amp;app=49&amp;f=JPEG?w=312&amp;h=208&amp;s=1A11408196234911188845F203009032\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 746989792144855077\"] > .rn-three-pic-content > .rn-three-pic-wrap:nth-child(2) > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,5,DIV,1,DIV,0,A,1,DIV,1,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3800483417,844282883&amp;fm=173&amp;app=49&amp;f=JPEG?w=312&amp;h=208&amp;s=5704D6AB68638EDE1859FDA303007003\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 746989792144855077\"] > .rn-three-pic-content > .rn-three-pic-wrap:nth-child(3) > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,5,DIV,1,DIV,0,A,1,DIV,2,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2632279595,1216295494&amp;fm=173&amp;app=49&amp;f=JPEG?w=312&amp;h=208&amp;s=FD541DC7085228D0480655320300D019\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\31 2209688148686140539\"] > .rn-small-video-wrap.rn-video-wrap > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,6,DIV,1,DIV,0,A,0,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss0.bdstatic.com/9bA1vGfa2gU2pMbfm9GUKT-w/timg?searchbox_feed&amp;size=f218_146&amp;quality=80&amp;wh_rate=0&amp;imgtype=0&amp;ref=http%3A%2F%2Fwww.baidu.com&amp;sec=0&amp;di=df1b88d6f418cc80ff3c4697022c41e2&amp;src=http%3A%2F%2Fpic.rmb.bdstatic.com%2F5b76998f481b4560f0095cea642fdc1f.jpeg\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 545683102936893545\"] > .rn-three-pic-content > .rn-three-pic-wrap:nth-child(1) > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,7,DIV,1,DIV,0,A,1,DIV,0,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2658358766,1284770639&amp;fm=173&amp;app=49&amp;f=JPEG?w=312&amp;h=208&amp;s=B9BC7F9598D052C429B514370300C060\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 545683102936893545\"] > .rn-three-pic-content > .rn-three-pic-wrap:nth-child(2) > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,7,DIV,1,DIV,0,A,1,DIV,1,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1937580919,1810285304&amp;fm=173&amp;app=49&amp;f=JPEG?w=312&amp;h=208&amp;s=B03B5F95F20B6F4D70A1146D0300D073\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}},{"node":{"type":"node","selector":"a[data-rid=\"\\39 545683102936893545\"] > .rn-three-pic-content > .rn-three-pic-wrap:nth-child(3) > img","path":"1,HTML,2,BODY,3,DIV,0,DIV,5,DIV,0,DIV,0,DIV,3,DIV,1,DIV,0,DIV,7,DIV,1,DIV,0,A,1,DIV,2,DIV,0,IMG","snippet":"\u003cimg src=\"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2629148719,529282553&amp;fm=173&amp;app=49&amp;f=JPEG?w=312&amp;h=208&amp;s=2E809C4DDE03454D1F31217A0300805A\">","explanation":"Fix any of the following:\n  Element does not have an alt attribute\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"img"}}],"debugData":{"type":"debugdata","impact":"critical","tags":["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"]}}},"input-image-alt":{"id":"input-image-alt","title":"`\u003cinput type=\"image\">` 元素包含 `[alt]` 文字","description":"将图片用作 `\u003cinput>` 按钮时，提供替代文字有助于屏幕阅读器用户了解该按钮的用途。[了解详情](https://web.dev/input-image-alt/)。","score":null,"scoreDisplayMode":"notApplicable"},"label":{"id":"label","title":"表单元素不具备关联的标签","description":"标签可确保辅助技术（如屏幕阅读器）正确读出表单控件。[了解详情](https://web.dev/label/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":"#index-kw","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,3,DIV,0,FORM,0,DIV,0,DIV,1,INPUT","snippet":"\u003cinput type=\"search\" autocomplete=\"off\" autocorrect=\"off\" maxlength=\"64\" id=\"index-kw\" name=\"word\" class=\"se-input adjust-input\" data-placeholder=\"\" data-sa=\"\" data-sug=\"1\">","explanation":"Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Form element does not have an implicit (wrapped) \u003clabel>\n  Form element does not have an explicit \u003clabel>\n  Element has no title attribute or the title attribute is empty","nodeLabel":"input"}}],"debugData":{"type":"debugdata","impact":"critical","tags":["cat.forms","wcag2a","wcag332","wcag131","section508","section508.22.n"]}}},"layout-table":{"id":"layout-table","title":"展示性 `\u003ctable>` 元素未使用 `\u003cth>`、`\u003ccaption>` 或 `[summary]` 属性。","description":"用于实现布局用途的表格不应包含数据元素（例如 th 或 caption 元素或 summary 属性），因为这会令屏幕阅读器用户感到困惑。[了解详情](https://web.dev/layout-table/)。","score":null,"scoreDisplayMode":"notApplicable"},"link-name":{"id":"link-name","title":"链接缺少可识别的名称","description":"请确保链接文字（以及用作链接的图片替代文字）可识别、独一无二且可成为焦点，这样做会提升屏幕阅读器用户的导航体验。[了解详情](https://web.dev/link-name/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":".square-enterance","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,0,DIV,2,A","snippet":"\u003ca class=\"square-enterance\" data-tclog=\"\" href=\"https://m.baidu.com/l=1/tc?logid=2346015140&amp;from=844b&amp;ref=index_iphone&amp;nsrc=IlPT2AEptyoA_yixCFOxCGZb8c3JV3T5ABfPNy6R2iv5nk_qva02FMNsUiH5Nn_KJoCa9m3BdMZObmGcWyNnn1E2e_&amp;bdenc=1&amp;ct=10&amp;cst=2&amp;logFrom=navs_square\">","explanation":"Fix all of the following:\n  Element is in tab order and does not have accessible text\n\nFix any of the following:\n  Element does not have text that is visible to screen readers\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element's default semantics were not overridden with role=\"presentation\"\n  Element's default semantics were not overridden with role=\"none\"","nodeLabel":"a"}}],"debugData":{"type":"debugdata","impact":"serious","tags":["cat.name-role-value","wcag2a","wcag412","wcag244","section508","section508.22.a"]}}},"list":{"id":"list","title":"列表只包含 `\u003cli>` 元素和脚本支持元素（`\u003cscript>` 和 `\u003ctemplate>`）。","description":"屏幕阅读器会采用特定的方法来读出列表内容。确保列表结构正确有助于屏幕阅读器顺利读出相应内容。[了解详情](https://web.dev/list/)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"listitem":{"id":"listitem","title":"列表项 (`\u003cli>`) 包含在 `\u003cul>` 或 `\u003col>` 父元素中","description":"屏幕阅读器要求列表项 (`\u003cli>`) 必须包含在父 `\u003cul>` 或 `\u003col>` 中，这样才能正确读出它们。[了解详情](https://web.dev/listitem/)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"meta-refresh":{"id":"meta-refresh","title":"文档未使用 `\u003cmeta http-equiv=\"refresh\">`","description":"用户并不希望网页自动刷新，因为自动刷新会不断地将焦点移回到页面顶部。这可能会让用户感到沮丧或困惑。[了解详情](https://web.dev/meta-refresh/)。","score":null,"scoreDisplayMode":"notApplicable"},"meta-viewport":{"id":"meta-viewport","title":"`\u003cmeta name=\"viewport\">` 元素中使用了 `[user-scalable=\"no\"]`，或者 `[maximum-scale]` 属性小于 5。","description":"对于必须依靠放大屏幕才能清晰看到网页内容的弱视用户而言，停用缩放功能会给他们带来问题。[了解详情](https://web.dev/meta-viewport/)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"node","itemType":"node","text":"未通过审核的元素"}],"items":[{"node":{"type":"node","selector":"meta[name=\"viewport\"]","path":"1,HTML,1,HEAD,2,META","snippet":"\u003cmeta name=\"viewport\" content=\"width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\">","explanation":"Fix any of the following:\n  user-scalable=no on \u003cmeta> tag disables zooming on mobile devices","nodeLabel":"meta"}}],"debugData":{"type":"debugdata","impact":"critical","tags":["cat.sensory-and-visual-cues","wcag2aa","wcag144"]}}},"object-alt":{"id":"object-alt","title":"`\u003cobject>` 元素包含 `[alt]` 文字","description":"屏幕阅读器无法转换非文字内容。向 `\u003cobject>` 元素添加替代文字可帮助屏幕阅读器将含义传达给用户。[了解详情](https://web.dev/object-alt/)。","score":null,"scoreDisplayMode":"notApplicable"},"tabindex":{"id":"tabindex","title":"所有元素的 `[tabindex]` 值都不大于 0","description":"值大于 0 意味着明确的导航顺序。尽管这在技术上可行，但往往会让依赖辅助技术的用户感到沮丧。[了解详情](https://web.dev/tabindex/)。","score":null,"scoreDisplayMode":"notApplicable"},"td-headers-attr":{"id":"td-headers-attr","title":"`\u003ctable>` 元素中使用 `[headers]` 属性的单元格引用的是同一表格中的单元格。","description":"屏幕阅读器提供了更便于用户浏览表格内容的功能。请确保那些使用 `[headers]` 属性的 `\u003ctd>` 单元格仅引用同一个表格中的其他单元格，这样做可提升屏幕阅读器用户的体验。[了解详情](https://web.dev/td-headers-attr/)。","score":null,"scoreDisplayMode":"notApplicable"},"th-has-data-cells":{"id":"th-has-data-cells","title":"`\u003cth>` 元素和 `[role=\"columnheader\"/\"rowheader\"]` 的元素具备它们所描述的数据单元格。","description":"屏幕阅读器提供了更便于用户浏览表格内容的功能。确保表格标头始终引用特定一组单元格可以提升屏幕阅读器用户的体验。[了解详情](https://web.dev/th-has-data-cells/)。","score":null,"scoreDisplayMode":"notApplicable"},"valid-lang":{"id":"valid-lang","title":"`[lang]` 属性的值有效","description":"为元素指定有效的 [BCP 47 语言](https://www.w3.org/International/questions/qa-choosing-language-tags#question)有助于确保屏幕阅读器正确读出文字。[了解详情](https://web.dev/valid-lang/)。","score":null,"scoreDisplayMode":"notApplicable"},"video-caption":{"id":"video-caption","title":"`\u003cvideo>` 元素包含带 `[kind=\"captions\"]` 的 `\u003ctrack>` 元素","description":"如果视频提供了字幕，失聪用户和听障用户便能更轻松地获取此视频中的信息。[了解详情](https://web.dev/video-caption/)。","score":null,"scoreDisplayMode":"notApplicable"},"video-description":{"id":"video-description","title":"`\u003cvideo>` 元素包含带 `[kind=\"description\"]` 的 `\u003ctrack>` 元素","description":"音频说明可提供对话框无法提供的视频相关信息（例如面部表情和场景）。[了解详情](https://web.dev/video-description/)。","score":null,"scoreDisplayMode":"notApplicable"},"custom-controls-labels":{"id":"custom-controls-labels","title":"Custom controls have associated labels","description":"Custom interactive controls have associated labels, provided by aria-label or aria-labelledby. [Learn more](https://web.dev/custom-controls-labels/).","score":null,"scoreDisplayMode":"manual"},"custom-controls-roles":{"id":"custom-controls-roles","title":"Custom controls have ARIA roles","description":"Custom interactive controls have appropriate ARIA roles. [Learn more](https://web.dev/custom-control-roles/).","score":null,"scoreDisplayMode":"manual"},"focus-traps":{"id":"focus-traps","title":"User focus is not accidentally trapped in a region","description":"A user can tab into and out of any control or region without accidentally trapping their focus. [Learn more](https://web.dev/focus-traps/).","score":null,"scoreDisplayMode":"manual"},"focusable-controls":{"id":"focusable-controls","title":"Interactive controls are keyboard focusable","description":"Custom interactive controls are keyboard focusable and display a focus indicator. [Learn more](https://web.dev/focusable-controls/).","score":null,"scoreDisplayMode":"manual"},"heading-levels":{"id":"heading-levels","title":"Headings don't skip levels","description":"Headings are used to create an outline for the page and heading levels are not skipped. [Learn more](https://web.dev/heading-levels/).","score":null,"scoreDisplayMode":"manual"},"interactive-element-affordance":{"id":"interactive-element-affordance","title":"Interactive elements indicate their purpose and state","description":"Interactive elements, such as links and buttons, should indicate their state and be distinguishable from non-interactive elements. [Learn more](https://web.dev/interactive-element-affordance/).","score":null,"scoreDisplayMode":"manual"},"logical-tab-order":{"id":"logical-tab-order","title":"The page has a logical tab order","description":"Tabbing through the page follows the visual layout. Users cannot focus elements that are offscreen. [Learn more](https://web.dev/logical-tab-order/).","score":null,"scoreDisplayMode":"manual"},"managed-focus":{"id":"managed-focus","title":"The user's focus is directed to new content added to the page","description":"If new content, such as a dialog, is added to the page, the user's focus is directed to it. [Learn more](https://web.dev/managed-focus/).","score":null,"scoreDisplayMode":"manual"},"offscreen-content-hidden":{"id":"offscreen-content-hidden","title":"Offscreen content is hidden from assistive technology","description":"Offscreen content is hidden with display: none or aria-hidden=true. [Learn more](https://web.dev/offscreen-content-hidden/).","score":null,"scoreDisplayMode":"manual"},"use-landmarks":{"id":"use-landmarks","title":"HTML5 landmark elements are used to improve navigation","description":"Landmark elements (\u003cmain>, \u003cnav>, etc.) are used to improve the keyboard navigation of the page for assistive technology. [Learn more](https://web.dev/use-landmarks/).","score":null,"scoreDisplayMode":"manual"},"visual-order-follows-dom":{"id":"visual-order-follows-dom","title":"Visual order on the page follows DOM order","description":"DOM order matches the visual order, improving navigation for assistive technology. [Learn more](https://web.dev/visual-order-follows-dom/).","score":null,"scoreDisplayMode":"manual"},"uses-long-cache-ttl":{"id":"uses-long-cache-ttl","title":"采用高效的缓存策略提供静态资源","description":"延长缓存期限可加快重访您网页的速度。[了解详情](https://web.dev/uses-long-cache-ttl)。","score":0.34,"scoreDisplayMode":"numeric","numericValue":213721.4244740973,"displayValue":"找到了 66 项资源","details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"网址"},{"key":"cacheLifetimeMs","itemType":"ms","text":"缓存 TTL","displayUnit":"duration"},{"key":"totalBytes","itemType":"bytes","text":"大小","displayUnit":"kb","granularity":1}],"items":[{"url":"https://sm.bdimg.com/static/wiseindex/fonts/n-icons_7bcbf44.woff","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":43313,"wastedBytes":43313},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/base/uilib/iconfont/iconfont_fcd5aba.woff?","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":29718,"wastedBytes":29718},{"url":"https://feed.baidu.com/feed/api/wise/feedlist?sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&ssid=0&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&qid=2346015140&clickDownload=0&tabId=1&sync=1&_=1585042747008&callback=jsonp2","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":29451,"wastedBytes":29451},{"url":"https://feed.baidu.com/feed/api/tab/gettabinfo?pd=wise&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&ssid=0&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&qid=2346015140&ms=1&cb=indJsonp&current_data=%22%22&_=1585042746857&cb=jsonp1","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":3254,"wastedBytes":3254},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042746817&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=index","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":441,"wastedBytes":441},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749078&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=2&ref=index_iphone&logFrom=callbaidu&logInfo=defaul_try","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":347,"wastedBytes":347},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749147&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=baidulogo&logoInfo=%7B%22origin%22%3A%221023197w%22%2C%22from%22%3A%22844b%22%2C%22channel%22%3A%221023206g%22%2C%22browserid%22%3A%2224%22%2C%22qid%22%3A%222346015140%22%2C%22timestamp%22%3A1585042749146%7D","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":347,"wastedBytes":347},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749152&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=A4&logInfo=%7B%22origin%22%3A%221023857w%22%2C%22from%22%3A%22844b%22%2C%22channel%22%3A%221023864w%22%2C%22browserid%22%3A%2224%22%2C%22qid%22%3A%222346015140%22%2C%22timestamp%22%3A1585042749149%2C%22experiment%22%3A%22single%22%2C%22action%22%3A%22show%22%7D","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":347,"wastedBytes":347},{"url":"https://m.baidu.com/tc?tcreq4log=1&r=1585042749953&logid=2346015140&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=10&cst=1&ref=index_iphone&logFrom=callbaidush&logInfo=%7B%22pos%22%3A3%2C%22browserid%22%3A%2224%22%2C%22from%22%3A%22844b%22%2C%22channel%22%3A%221023864w%22%2C%22source%22%3A%221023857w%22%2C%22show%22%3A1%7D","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":347,"wastedBytes":347},{"url":"https://hpd.baidu.com/v.gif?logid=2346015140&ssid=0&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&ct=1&cst=1&logFrom=mid_news&logInfo=a2_l*&logExtra=%7B%22st%22%3A%22news%22%2C%22rid%22%3A%229275447518675333919%22%2C%22isBaijiahao%22%3A1%2C%22extra%22%3A%22%7B%5C%22rec_src%5C%22%3A%5B52%5D%2C%5C%22mark%5C%22%3A0%2C%5C%22mark_rec%5C%22%3A0%2C%5C%22round_loop_ids%5C%22%3A%5B100%2C200%5D%2C%5C%22top%5C%22%3A1%2C%5C%22ua%5C%22%3A%5C%220_0__0_240%5C%22%2C%5C%22ut%5C%22%3A%5C%22%5C%22%2C%5C%22province%5C%22%3A%5C%22%5C%5Cu6e56%5C%5Cu5317%5C%22%2C%5C%22city%5C%22%3A%5C%22%5C%5Cu9ec4%5C%5Cu5188%5C%22%2C%5C%22district%5C%22%3A%5C%22%5C%22%2C%5C%22channel_id%5C%22%3A1%2C%5C%22session_id%5C%22%3A%5C%2215850427466914%5C%22%2C%5C%22refresh_index%5C%22%3A%5C%22%5C%22%2C%5C%22position%5C%22%3A0%2C%5C%22log_id%5C%22%3A2346735357%2C%5C%22refresh_state%5C%22%3A1%2C%5C%22city_code%5C%22%3A%5C%22271%5C%22%2C%5C%22local_city%5C%22%3A-1%2C%5C%22user_type%5C%22%3A1%2C%5C%22refresh_type%5C%22%3A1%2C%5C%22refresh_timestamp_ms%5C%22%3A1585042746766%2C%5C%22cs%5C%22%3A%5C%22906297783%20497651126%5C%22%2C%5C%22gr_policy_flag%5C%22%3A0%2C%5C%22final_score%5C%22%3A3%2C%5C%22author_authority_score_v1%5C%22%3A2%2C%5C%22audit_final_score%5C%22%3A3%2C%5C%22predictor_q_score%5C%22%3A0%2C%5C%22vertical_types%5C%22%3A%5B0%2C26%5D%2C%5C%22templates%5C%22%3A%7B%5C%22id%5C%22%3A%5B30%2C30%5D%7D%2C%5C%22wifiinfo%5C%22%3A%5C%22%5C%22%2C%5C%22gr_original_pos%5C%22%3A0%2C%5C%22gr_step_click%5C%22%3A0.0091728856787086%2C%5C%22gr_step_related_click%5C%22%3A6.8901966187696e-5%2C%5C%22dispatch_time%5C%22%3A1585042746%2C%5C%22msrcid%5C%22%3A80001%2C%5C%22mthid%5C%22%3A%5C%221587267721576374%5C%22%2C%5C%22mrtype%5C%22%3A%5C%22text%5C%22%7D%22%2C%22title%22%3A%22%E4%B8%80%E5%A4%A93%E6%AC%A1%E9%80%9A%E8%AF%9D%EF%BC%8C%E4%B9%A0%E4%B8%BB%E5%B8%AD%E5%AF%86%E9%9B%86%E5%8F%91%E5%87%BA%E5%9B%A2%E7%BB%93%E5%90%88%E4%BD%9C%E7%9A%84%E4%B8%AD%E5%9B%BD%E5%80%A1%E8%AE%AE%22%2C%22picNum%22%3A0%2C%22stype%22%3A0%2C%22itemType%22%3A%22newsTitle%22%2C%22pos%22%3A1%7D%2C%7B%22st%22%3A%22news%22%2C%22rid%22%3A%229069318972944726870%22%2C%22isBaijiahao%22%3A1%2C%22extra%22%3A%22%7B%5C%22rec_src%5C%22%3A%5B999%5D%2C%5C%22type%5C%22%3A0%2C%5C%22mark%5C%22%3A0%2C%5C%22attentionnum%5C%22%3A0%2C%5C%22th%5C%22%3A-1%2C%5C%22ua%5C%22%3A%5C%220_0__0_240%5C%22%2C%5C%22ut%5C%22%3A%5C%22%5C%22%2C%5C%22province%5C%22%3A%5C%22%5C%5Cu6e56%5C%5Cu5317%5C%22%2C%5C%22city%5C%22%3A%5C%22%5C%5Cu9ec4%5C%5Cu5188%5C%22%2C%5C%22district%5C%22%3A%5C%22%5C%22%2C%5C%22channel_id%5C%22%3A1%2C%5C%22round_loop_ids%5C%22%3A%5B200%5D%2C%5C%22session_id%5C%22%3A%5C%2215850427466914%5C%22%2C%5C%22refresh_index%5C%22%3A%5C%22%5C%22%2C%5C%22position%5C%22%3A1%2C%5C%22log_id%5C%22%3A2346735357%2C%5C%22refresh_state%5C%22%3A1%2C%5C%22city_code%5C%22%3A%5C%22271%5C%22%2C%5C%22local_city%5C%22%3A-1%2C%5C%22user_type%5C%22%3A1%2C%5C%22refresh_type%5C%22%3A1%2C%5C%22refresh_timestamp_ms%5C%22%3A1585042746766%2C%5C%22cs%5C%22%3A%5C%223966240335%201299908375%5C%22%2C%5C%22gr_policy_flag%5C%22%3A0%2C%5C%22final_score%5C%22%3A2%2C%5C%22author_authority_score_v1%5C%22%3A4%2C%5C%22audit_final_score%5C%22%3A3%2C%5C%22news_style_super%5C%22%3A%5C%22%5C%5Cu8d1f%5C%5Cu9762%2C%5C%5Cu753b%5C%5Cu98ce%5C%5Cu7c97%5C%5Cu52a3%5C%22%2C%5C%22predictor_q_score%5C%22%3A0%2C%5C%22vertical_types%5C%22%3A%5B0%2C26%5D%2C%5C%22templates%5C%22%3A%7B%5C%22id%5C%22%3A%5B30%5D%7D%2C%5C%22wifiinfo%5C%22%3A%5C%22%5C%22%2C%5C%22gr_original_pos%5C%22%3A1%2C%5C%22gr_step_click%5C%22%3A0.045161370187998%2C%5C%22gr_step_related_click%5C%22%3A0.00010657673283276%2C%5C%22overwrite%5C%22%3A1%2C%5C%22dispatch_time%5C%22%3A1585042746%2C%5C%22msrcid%5C%22%3A80001%2C%5C%22mthid%5C%22%3A%5C%221552864910655429%5C%22%2C%5C%22mrtype%5C%22%3A%5C%22text%5C%22%7D%22%2C%22title%22%3A%22%E5%85%A8%E7%90%83%E6%96%B0%E5%86%A0%E8%82%BA%E7%82%8E%E7%A1%AE%E8%AF%8A%E7%97%85%E4%BE%8B%E8%B6%85%E8%BF%8738%E4%B8%87%E4%BE%8B%20%E7%BE%8E%E5%9B%BD%E8%B6%854.6%E4%B8%87%E4%BE%8B%22%2C%22picNum%22%3A0%2C%22stype%22%3A0%2C%22isbdopen%22%3A1%2C%22itemType%22%3A%22newsTitle%22%2C%22pos%22%3A2%2C%22xsourceTag%22%3Atrue%7D&tid=2066&r=l1585042748114","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":130,"wastedBytes":130},{"url":"https://hpd.baidu.com/v.gif?tid=13&ct=1&cst=1&logFrom=index&logInfo=index&ssid=0&from=844b&pu=sz%40320_1001%2Cta%40iphone_2_6.0_24_74.0&qid=2346015140&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&logid=2346015140&ref=index_iphone&r=l1585042746509","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":130,"wastedBytes":130},{"url":"https://m.baidu.com/tcbox?service=bdbox&action=pblog&ctv=2&cen=uid_ua_ut&data=%7B%22appid%22%3A%221%22%2C%22dataid%22%3A%222%22%2C%22actiontype%22%3A%221%22%2C%22actionid%22%3A%222%22%2C%22actiondata%22%3A%7B%22ref%22%3A%22%22%2C%22gmv%22%3A%22%22%2C%22source%22%3A%22%22%2C%22boxVersion%22%3A0%2C%22boxPlatform%22%3A%22android%22%2C%22evtName%22%3A%22openBox%22%2C%22evtType%22%3A%221021206d%22%2C%22evtTag%22%3A%7B%22source%22%3A%221021206d%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22chrome%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22%22%2C%22channel%22%3A%221021206r%22%2C%22extlog%22%3A%22%22%2C%22baiduId%22%3A%2288C7BD6C60D47AD71CFBE516CB4A166B%3AFG%3D1%22%2C%22app_now%22%3A%22chrome_1585042749079_3561962775%22%2C%22yyb_pkg%22%3A%22com.baidu.searchbox%22%2C%22idmData%22%3A%7B%22firstOpen%22%3A%22lite%22%2C%22secondOpen%22%3A%22main%22%2C%22status%22%3A%220%22%2C%22timeout%22%3A1585129147042%7D%2C%22matrix%22%3A%22lite%22%7D%7D%2C%22cateid%22%3A14%7D&_rnd=1790118702","cacheLifetimeMs":0,"cacheHitProbability":0,"totalBytes":0,"wastedBytes":0},{"url":"https://s.bdstatic.com/common/openjs/openBox.js?_v=2020-03-24-17","debugData":{"type":"debugdata","max-age":3600},"cacheLifetimeMs":3600000,"cacheHitProbability":0.2,"totalBytes":12485,"wastedBytes":9988},{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/duobao.jpg","cacheLifetimeMs":75511000,"cacheHitProbability":0.5747939814814814,"totalBytes":163741,"wastedBytes":69623.65867824075},{"url":"https://m.baidu.com/bdlogo/squareicon_e582f4c48e93901e747536ad982e030d.png","debugData":{"type":"debugdata","max-age":86400},"cacheLifetimeMs":86400000,"cacheHitProbability":0.6,"totalBytes":834,"wastedBytes":333.6},{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/report.png","cacheLifetimeMs":253242000,"cacheHitProbability":0.7931041666666667,"totalBytes":1782,"wastedBytes":368.6883749999999},{"url":"https://sv.bdstatic.com/static/fecommon/growth/release/core.js?_sv=2020032417","debugData":{"type":"debugdata","max-age":1209600},"cacheLifetimeMs":1209600000,"cacheHitProbability":0.9019553072625699,"totalBytes":25315,"wastedBytes":2482.0013966480433},{"url":"https://sm.bdimg.com/static/wiseindex/js/package/newsActivity_20ba6a6.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":33335,"wastedBytes":3119.336592178769},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/atomWrapper_6fc442d.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":22215,"wastedBytes":2078.7779329608925},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/invoke-box_3f05010.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":12149,"wastedBytes":1136.8477653631278},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/ralltiir_489d038.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":11414,"wastedBytes":1068.069832402234},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/Boxjs-amd_1cd9b4a.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":7957,"wastedBytes":744.579608938547},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/Boxjs-search_2ce639b.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":5584,"wastedBytes":522.5251396648041},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/component/btmBanner_f91323e.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":5140,"wastedBytes":480.9776536312846},{"url":"https://s.bdstatic.com/common/openjs/amd/eslx.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":3994,"wastedBytes":373.7402234636869},{"url":"https://sm.bdimg.com/static/wiseindex/js/plugin/safariicon_6bd009a.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":3539,"wastedBytes":331.1634078212289},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/BdrainswDislike/dist/index_f95793e.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":3055,"wastedBytes":285.8729050279328},{"url":"https://sm.bdimg.com/static/wiseindex/js/package/superframe_5b7bdae.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":3013,"wastedBytes":281.9427374301674},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/a4/carousel_408bced.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":2991,"wastedBytes":279.8840782122903},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/Carousel_76e2bc0.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":2605,"wastedBytes":243.76396648044678},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/channelMgr/index_c70dc69.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":2373,"wastedBytes":222.05446927374288},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/invokeSecr_13c5fec.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":2238,"wastedBytes":209.42178770949707},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/underscore_23fe246.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":2006,"wastedBytes":187.7122905027932},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/img/baiduappAdCloseWhite_b84ffa8.png","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1917,"wastedBytes":179.3840782122904},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/promise_ac4cb03.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1597,"wastedBytes":149.43994413407813},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/component/fullscreen_f01324e.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1498,"wastedBytes":140.1759776536312},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/fnProvider_9833c78.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1497,"wastedBytes":140.0824022346368},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/wise-invoke-popup_fa02b72.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1486,"wastedBytes":139.05307262569823},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/newtab/img/fetch_ing_8_0.png","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1190,"wastedBytes":111.3547486033519},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/Core_426be15.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1186,"wastedBytes":110.98044692737423},{"url":"https://sm.bdimg.com/static/wiseindex/img/fetch_ing_8_0.png","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1161,"wastedBytes":108.6410614525139},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/user-agent_24ce52d.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1131,"wastedBytes":105.8337988826815},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/ShieldMonitor_b61052e.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1079,"wastedBytes":100.96787709497201},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/ivkBox_2c53958.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":1031,"wastedBytes":96.47625698324016},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/invokeCookie_2b36f0c.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":993,"wastedBytes":92.92039106145246},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/invokeBox_12354c1.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":969,"wastedBytes":90.67458100558653},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/setFullScreenIvkCK_92b17a0.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":892,"wastedBytes":83.46927374301671},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/serverDataFactory_568f951.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":860,"wastedBytes":80.47486033519549},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/StrategyDataProcess_787f12d.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":715,"wastedBytes":66.90642458100555},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/DataProcess_deb477f.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":664,"wastedBytes":62.13407821229046},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/log_8406fdd.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":649,"wastedBytes":60.73044692737427},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/common/bannerConfig_9ec6e61.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":621,"wastedBytes":58.11033519553069},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/logo/logo_857fccc.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":567,"wastedBytes":53.05726256983237},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/jssdk_6c0ef3a.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":553,"wastedBytes":51.747206703910585},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/component/background_0a042a0.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":544,"wastedBytes":50.90502793296086},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/transfer/bubble/bubble_ba92dca.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":540,"wastedBytes":50.53072625698321},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/getInvokeLogData_fc32168.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":515,"wastedBytes":48.19134078212288},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@baidu/get-app-info_2747ad8.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":451,"wastedBytes":42.202513966480424},{"url":"https://sm.bdimg.com/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":451,"wastedBytes":42.202513966480424},{"url":"https://sm.bdimg.com/static/wiseindex/js/lib/invoke/setIvkCK_bb46616.js","debugData":{"type":"debugdata","max-age":2592000},"cacheLifetimeMs":2592000000,"cacheHitProbability":0.9064245810055866,"totalBytes":364,"wastedBytes":34.06145251396646},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3800483417,844282883&fm=173&app=49&f=JPEG?w=312&h=208&s=5704D6AB68638EDE1859FDA303007003","debugData":{"type":"debugdata","max-age":2628000},"cacheLifetimeMs":2628000000,"cacheHitProbability":0.9065409683426443,"totalBytes":22257,"wastedBytes":2080.117667597766},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2632279595,1216295494&fm=173&app=49&f=JPEG?w=312&h=208&s=FD541DC7085228D0480655320300D019","debugData":{"type":"debugdata","max-age":2628000},"cacheLifetimeMs":2628000000,"cacheHitProbability":0.9065409683426443,"totalBytes":18130,"wastedBytes":1694.4122439478588},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2658358766,1284770639&fm=173&app=49&f=JPEG?w=312&h=208&s=B9BC7F9598D052C429B514370300C060","debugData":{"type":"debugdata","max-age":2628000},"cacheLifetimeMs":2628000000,"cacheHitProbability":0.9065409683426443,"totalBytes":17312,"wastedBytes":1617.962756052142},{"url":"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2629148719,529282553&fm=173&app=49&f=JPEG?w=312&h=208&s=2E809C4DDE03454D1F31217A0300805A","debugData":{"type":"debugdata","max-age":2628000},"cacheLifetimeMs":2628000000,"cacheHitProbability":0.9065409683426443,"totalBytes":14275,"wastedBytes":1334.1276769087526},{"url":"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1937580919,1810285304&fm=173&app=49&f=JPEG?w=312&h=208&s=B03B5F95F20B6F4D70A1146D0300D073","debugData":{"type":"debugdata","max-age":2628000},"cacheLifetimeMs":2628000000,"cacheHitProbability":0.9065409683426443,"totalBytes":14201,"wastedBytes":1327.2117085661082},{"url":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3318486632,1339666056&fm=173&app=49&f=JPEG?w=312&h=208&s=1A11408196234911188845F203009032","debugData":{"type":"debugdata","max-age":2628000},"cacheLifetimeMs":2628000000,"cacheHitProbability":0.9065409683426443,"totalBytes":12083,"wastedBytes":1129.265479515829}],"summary":{"wastedBytes":213721.4244740973}}},"total-byte-weight":{"id":"total-byte-weight","title":"避免网络负载过大","description":"网络负载过大不仅会让用户付出真金白银，还极有可能会延长加载用时。[了解详情](https://web.dev/total-byte-weight)。","score":1,"scoreDisplayMode":"numeric","numericValue":974958,"displayValue":"总大小为 952 KB","details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"网址"},{"key":"totalBytes","itemType":"bytes","text":"大小"}],"items":[{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/duobao.jpg","totalBytes":163741},{"url":"https://www.baidu.com/?action=static&ms=1&version=css_page_2@0,css_callapp@0,css_weather@0,css_icon@0,css_plus@0,css_edit@0,css_modal@0,css_widget_sug@0,css_skin@0,js_esl@0,js_zepto@0,js_event@0,js_fastclick@0,js_utils@0,js_smartymonkey@0,js_index@0,js_banner_ctrl@0,js_inputlog@0,js_bdnow@0,js_nctips@0,js_widget_textinput@0,js_widget_sug@0,js_mp@0,js_hash_lib@0,js_skinRenderIndex@0,js_skinIphone@0,js_prefetch@0,js_sug@0,js_iscroll@0,js_superframe@0,js_init@0,js_geolocation@0,js_login@0,js_tab@0,js_md5@0,js_url@0,js_lswrite@0,js_modal@0,js_thirdparty@0,js_m_monitor@0,js_superstart@0,js_baiduloc@0,js_callbaiduapp_android@0&callback=B.getCode&r=248&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085","totalBytes":154395},{"url":"https://www.baidu.com/","totalBytes":90780},{"url":"https://sm.bdimg.com/static/wiseindex/fonts/n-icons_7bcbf44.woff","totalBytes":43313},{"url":"https://sm.bdimg.com/static/wiseindex/js/package/newsActivity_20ba6a6.js","totalBytes":33335},{"url":"https://m.baidu.com/static/index/plus/plus_logo_web.png","totalBytes":30099},{"url":"https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/itemrep/base/uilib/iconfont/iconfont_fcd5aba.woff?","totalBytes":29718},{"url":"https://feed.baidu.com/feed/api/wise/feedlist?sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&ssid=0&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&qid=2346015140&clickDownload=0&tabId=1&sync=1&_=1585042747008&callback=jsonp2","totalBytes":29451},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/spritelist_71904c7.png","totalBytes":28854},{"url":"https://sv.bdstatic.com/static/fecommon/growth/release/core.js?_sv=2020032417","totalBytes":25315}]}},"offscreen-images":{"id":"offscreen-images","title":"推迟加载屏幕外图片","description":"建议您在所有关键资源加载完毕后推迟加载屏幕外图片和处于隐藏状态的图片，从而缩短可交互前的耗时。[了解详情](https://web.dev/offscreen-images)。","score":0.64,"scoreDisplayMode":"numeric","numericValue":490,"displayValue":"有望节省 89 KB","warnings":[],"details":{"type":"opportunity","headings":[{"key":"url","valueType":"thumbnail","label":""},{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/spritelist_71904c7.png","requestStartTime":370271.285241,"totalBytes":28351,"wastedBytes":28351,"wastedPercent":100},{"url":"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2629148719,529282553&fm=173&app=49&f=JPEG?w=312&h=208&s=2E809C4DDE03454D1F31217A0300805A","requestStartTime":370271.602898,"totalBytes":13931,"wastedBytes":13931,"wastedPercent":100},{"url":"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1937580919,1810285304&fm=173&app=49&f=JPEG?w=312&h=208&s=B03B5F95F20B6F4D70A1146D0300D073","requestStartTime":370271.602414,"totalBytes":13852,"wastedBytes":13852,"wastedPercent":100},{"url":"https://m.baidu.com/se/static/img/iphone/logo.png","requestStartTime":370270.804035,"totalBytes":13750,"wastedBytes":13750,"wastedPercent":100},{"url":"https://m.baidu.com/se/static/img/iphone/tab_loading__bg_logo.png","requestStartTime":370270.804274,"totalBytes":8214,"wastedBytes":8214,"wastedPercent":100},{"url":"https://ss0.bdstatic.com/9bA1vGfa2gU2pMbfm9GUKT-w/timg?searchbox_feed&size=f218_146&quality=80&wh_rate=0&imgtype=0&ref=http%3A%2F%2Fwww.baidu.com&sec=0&di=df1b88d6f418cc80ff3c4697022c41e2&src=http%3A%2F%2Fpic.rmb.bdstatic.com%2F5b76998f481b4560f0095cea642fdc1f.jpeg","requestStartTime":370271.600208,"totalBytes":2974,"wastedBytes":2974,"wastedPercent":100},{"url":"https://m.baidu.com/static/index/plus/public/icon_police.png","requestStartTime":370270.799659,"totalBytes":2798,"wastedBytes":2798,"wastedPercent":100},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/fankui_cc44349.png","requestStartTime":370271.283568,"totalBytes":2684,"wastedBytes":2684,"wastedPercent":100},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/shoucang_5ef89d6.png","requestStartTime":370271.256778,"totalBytes":2374,"wastedBytes":2374,"wastedPercent":100},{"url":"https://m.baidu.com/static/index/plus/public/tab_news.png","requestStartTime":370271.296555,"totalBytes":2259,"wastedBytes":2259,"wastedPercent":100}],"overallSavingsMs":490,"overallSavingsBytes":91187}},"render-blocking-resources":{"id":"render-blocking-resources","title":"移除阻塞渲染的资源","description":"资源阻止了系统对您网页的首次渲染。建议以内嵌方式提供关键的 JS/CSS，并推迟提供所有非关键的 JS/样式。[了解详情](https://web.dev/render-blocking-resources)。","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"","details":{"type":"opportunity","headings":[],"items":[],"overallSavingsMs":0}},"unminified-css":{"id":"unminified-css","title":"缩减 CSS","description":"缩减 CSS 文件大小可缩减网络负载规模。[了解详情](https://web.dev/unminified-css)。","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"","details":{"type":"opportunity","headings":[],"items":[],"overallSavingsMs":0,"overallSavingsBytes":0}},"unminified-javascript":{"id":"unminified-javascript","title":"缩减 JavaScript","description":"如果缩减 JavaScript 文件大小，则既能缩减负载规模，又能缩短脚本解析用时。[了解详情](https://web.dev/unminified-javascript)。","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"有望节省 12 KB","warnings":[],"details":{"type":"opportunity","headings":[{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"https://sv.bdstatic.com/static/fecommon/growth/release/core.js?_sv=2020032417","totalBytes":25315,"wastedBytes":12098,"wastedPercent":47.79177790694238}],"overallSavingsMs":0,"overallSavingsBytes":12098}},"unused-css-rules":{"id":"unused-css-rules","title":"移除未使用的 CSS","description":"从样式表中移除无效规则并延迟加载首屏内容未使用的 CSS 可减少网络活动的无谓消耗。[了解详情](https://web.dev/unused-css-rules)。","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"有望节省 24 KB","details":{"type":"opportunity","headings":[{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"body,h1,h2,h3,p,div,ol,ul,input,button{margin:0;padding:0} ...","wastedBytes":24976,"wastedPercent":85.26355196166517,"totalBytes":29293}],"overallSavingsMs":0,"overallSavingsBytes":24976}},"uses-webp-images":{"id":"uses-webp-images","title":"采用新一代格式提供图片","description":"JPEG 2000、JPEG XR 和 WebP 等图片格式的压缩效果通常比 PNG 或 JPEG 好，因此下载速度更快，消耗的数据流量更少。[了解详情](https://web.dev/uses-webp-images)。","score":0.49,"scoreDisplayMode":"numeric","numericValue":800,"displayValue":"有望节省 189 KB","warnings":[],"details":{"type":"opportunity","headings":[{"key":"url","valueType":"thumbnail","label":""},{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/duobao.jpg","fromProtocol":true,"isCrossOrigin":true,"totalBytes":163096,"wastedBytes":135182},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/default_icon_02f13d8.png","fromProtocol":true,"isCrossOrigin":true,"totalBytes":24341,"wastedBytes":20455},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/spritelist_71904c7.png","fromProtocol":true,"isCrossOrigin":true,"totalBytes":28351,"wastedBytes":19325},{"url":"https://m.baidu.com/static/index/plus/plus_logo_web.png","fromProtocol":true,"isCrossOrigin":true,"totalBytes":29628,"wastedBytes":18444}],"overallSavingsMs":800,"overallSavingsBytes":193406}},"uses-optimized-images":{"id":"uses-optimized-images","title":"对图片进行高效编码","description":"如果图片经过了优化，则加载速度会更快，且消耗的移动数据网络流量会更少。[了解详情](https://web.dev/uses-optimized-images)。","score":0.88,"scoreDisplayMode":"numeric","numericValue":150,"displayValue":"有望节省 101 KB","warnings":[],"details":{"type":"opportunity","headings":[{"key":"url","valueType":"thumbnail","label":""},{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"https://b.bdstatic.com/searchbox/icms/searchbox/img/duobao.jpg","fromProtocol":true,"isCrossOrigin":true,"totalBytes":163096,"wastedBytes":103177}],"overallSavingsMs":150,"overallSavingsBytes":103177}},"uses-text-compression":{"id":"uses-text-compression","title":"启用文本压缩","description":"对于文本资源，应先压缩（gzip、deflate 或 brotli），然后再提供，以最大限度地减少网络活动消耗的字节总数。[了解详情](https://web.dev/uses-text-compression)。","score":0.93,"scoreDisplayMode":"numeric","numericValue":90,"displayValue":"有望节省 2 KB","details":{"type":"opportunity","headings":[{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"https://feed.baidu.com/feed/api/tab/gettabinfo?pd=wise&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085&ssid=0&from=844b&pu=sz%2540320_1001%252Cta%2540iphone_2_6.0_24_74.0&qid=2346015140&ms=1&cb=indJsonp&current_data=%22%22&_=1585042746857&cb=jsonp1","totalBytes":2886,"wastedBytes":2534}],"overallSavingsMs":90,"overallSavingsBytes":2534}},"uses-responsive-images":{"id":"uses-responsive-images","title":"适当调整图片大小","description":"提供大小合适的图片可节省移动数据网络流量并缩短加载用时。[了解详情](https://web.dev/uses-responsive-images)。","score":0.86,"scoreDisplayMode":"numeric","numericValue":170,"displayValue":"有望节省 16 KB","warnings":[],"details":{"type":"opportunity","headings":[{"key":"url","valueType":"thumbnail","label":""},{"key":"url","valueType":"url","label":"网址"},{"key":"totalBytes","valueType":"bytes","label":"大小"},{"key":"wastedBytes","valueType":"bytes","label":"可能达到的节省程度"}],"items":[{"url":"https://m.baidu.com/static/index/plus/plus_logo_web.png","totalBytes":29628,"wastedBytes":6985,"wastedPercent":23.57670454545454},{"url":"https://m.baidu.com/se/static/wiseatom/personalcenter/assets/img/default_icon_02f13d8.png","totalBytes":24341,"wastedBytes":5705,"wastedPercent":23.4375},{"url":"https://m.baidu.com/se/static/img/iphone/logo.png","totalBytes":13750,"wastedBytes":3512,"wastedPercent":25.540821829163075}],"overallSavingsMs":170,"overallSavingsBytes":16202}},"efficient-animated-content":{"id":"efficient-animated-content","title":"使用视频格式提供动画内容","description":"使用大型 GIF 提供动画内容会导致效率低下。建议您改用 MPEG4/WebM 视频（来提供动画）和 PNG/WebP（来提供静态图片）以减少网络活动消耗的字节数。[了解详情](https://web.dev/efficient-animated-content)","score":1,"scoreDisplayMode":"numeric","numericValue":0,"displayValue":"","details":{"type":"opportunity","headings":[],"items":[],"overallSavingsMs":0,"overallSavingsBytes":0}},"appcache-manifest":{"id":"appcache-manifest","title":"请勿使用应用缓存","description":"应用缓存已被弃用。[了解详情](https://web.dev/appcache-manifest)。","score":1,"scoreDisplayMode":"binary"},"doctype":{"id":"doctype","title":"页面包含 HTML DOCTYPE","description":"指定 DOCTYPE 会阻止浏览器切换到怪异模式。[了解详情](https://web.dev/doctype)。","score":1,"scoreDisplayMode":"binary"},"dom-size":{"id":"dom-size","title":"避免 DOM 规模过大","description":"浏览器工程师建议，页面包含的 DOM 元素最好少于 1,500 个左右。理想状况是，树深度少于 32 个元素，且少于 60 个子/父元素。大型 DOM 可能会增加内存使用量、导致[样式计算](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations)用时延长，并产生高昂的[布局重排](https://developers.google.com/speed/articles/reflow)费用。[了解详情](https://web.dev/dom-size)。","score":1,"scoreDisplayMode":"numeric","numericValue":441,"displayValue":"441 个元素","details":{"type":"table","headings":[{"key":"statistic","itemType":"text","text":"统计信息"},{"key":"element","itemType":"code","text":"元素"},{"key":"value","itemType":"numeric","text":"值"}],"items":[{"statistic":"DOM 元素总数","element":"","value":"441"},{"statistic":"最大 DOM 深度","element":{"type":"code","value":"\u003ci>"},"value":"16"},{"statistic":"子元素数量最大值","element":{"type":"code","value":"\u003cbody data-version=\"css_page_2@w-e1d30ac9,css_callapp@w-cfa28287,css_weather@w-025f53e0,css_icon@w-f168dca8,css_plus@w-c87478b7,css_edit@w-615a2d8c,css_modal@w-cdab584c,css_widget_sug@w-ec5ec8df,css_skin@w-27c43eae,js_esl@w-0affba88,js_zepto@w-012b12e3,js_event@w-9ad00288,js_fastclick@,js_utils@,js_smartymonkey@w-116ab7cb,js_index@w-d9375915,js_banner_ctrl@w-b194fb40,js_inputlog@w-228a5e0e,js_bdnow@w-2981c0e4,js_nctips@w-e32af532,js_widget_textinput@w-0f7bc28e,js_widget_sug@w-619a2cde,js_mp@w-8d93d84b,js_hash_lib@w-4598392e,js_skinRenderIndex@w-a467f3f8,js_skinIphone@w-e36528f4,js_prefetch@w-453350c7,js_sug@w-ac798920,js_iscroll@w-c02b295e,js_superframe@w-5c254153,js_init@w-997152e8,js_geolocation@w-a8094a1f,js_login@w-473c448e,js_tab@w-99663e3b,js_md5@w-d9ce29c6,js_url@w-39727df9,js_lswrite@w-29872e55,js_modal@w-bb611e58,js_thirdparty@w-c9b14877,js_m_monitor@w-8456a19f,js_superstart@w-e7dffdf3,js_baiduloc@w-4c4858ee,js_callbaiduapp_android@w-299f9ba1\" data-cur-page=\"index\" class=\" switch-iphone \">"},"value":"54"}]}},"external-anchors-use-rel-noopener":{"id":"external-anchors-use-rel-noopener","title":"指向跨域目的地的链接不安全","description":"向任何外部链接添加 `rel=\"noopener\"` 或 `rel=\"noreferrer\"`，可提高性能并减少安全漏洞。[了解详情](https://web.dev/external-anchors-use-rel-noopener)。","score":0,"scoreDisplayMode":"binary","warnings":[],"details":{"type":"table","headings":[{"key":"href","itemType":"url","text":"网址"},{"key":"target","itemType":"text","text":"目标"},{"key":"rel","itemType":"text","text":"Rel"}],"items":[{"href":"http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11000002000001","target":"_blank","rel":"","outerHTML":"\u003ca class=\"recordcode\" href=\"http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11000002000001\" target=\"_blank\">"}]}},"geolocation-on-start":{"id":"geolocation-on-start","title":"避免在网页加载时请求地理定位权限","description":"如果网站在缺少上下文的情况下请求位置，会导致用户不信任网站或感到困惑。建议将请求与用户操作进行绑定。[了解详情](https://web.dev/geolocation-on-start)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"no-document-write":{"id":"no-document-write","title":"请勿使用 `document.write()`","description":"对于连接速度较慢的用户，通过 `document.write()` 动态注入的外部脚本可将网页加载延迟数十秒。[了解详情](https://web.dev/no-document-write)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"no-vulnerable-libraries":{"id":"no-vulnerable-libraries","title":"避免使用含已知安全漏洞的前端 JavaScript 库","description":"某些第三方脚本可能包含已知的安全漏洞，攻击者很容易识别和利用这些漏洞。[了解详情](https://web.dev/no-vulnerable-libraries)。","score":1,"scoreDisplayMode":"binary","displayValue":"","details":{"type":"table","headings":[],"items":[],"summary":{}}},"js-libraries":{"id":"js-libraries","title":"已检测到的 JavaScript 库","description":"页面上检测到的所有前端 JavaScript 库。[了解详情](https://web.dev/js-libraries)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"name","itemType":"text","text":"名称"},{"key":"version","itemType":"text","text":"版本"}],"items":[{"name":"jQuery (Fast path)","npm":"jquery"},{"name":"Zepto.js","npm":"zepto"},{"name":"Vue","npm":"vue"}],"summary":{}}},"notification-on-start":{"id":"notification-on-start","title":"避免在网页加载时请求通知权限","description":"如果网站在缺少上下文的情况下请求发送通知，会导致用户不信任网站或感到困惑。建议将请求与用户手势进行绑定。[了解详情](https://web.dev/notification-on-start)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"password-inputs-can-be-pasted-into":{"id":"password-inputs-can-be-pasted-into","title":"允许用户粘贴内容到密码字段","description":"阻止密码粘贴，会破坏良好的安全政策。[了解详情](https://web.dev/password-inputs-can-be-pasted-into)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"uses-http2":{"id":"uses-http2","title":"没有对所有网页资源使用 HTTP/2","description":"HTTP/2 提供了许多优于 HTTP/1.1的优点，包括二进制标头、多路复用和服务器推送等。[了解详情](https://web.dev/uses-http2)。","score":0,"scoreDisplayMode":"binary","displayValue":"2 条请求未通过 HTTP/2 传送","details":{"type":"table","headings":[{"key":"url","itemType":"url","text":"网址"},{"key":"protocol","itemType":"text","text":"协议"}],"items":[{"protocol":"http/1.1","url":"https://www.baidu.com/"},{"protocol":"http/1.1","url":"https://www.baidu.com/?action=static&ms=1&version=css_page_2@0,css_callapp@0,css_weather@0,css_icon@0,css_plus@0,css_edit@0,css_modal@0,css_widget_sug@0,css_skin@0,js_esl@0,js_zepto@0,js_event@0,js_fastclick@0,js_utils@0,js_smartymonkey@0,js_index@0,js_banner_ctrl@0,js_inputlog@0,js_bdnow@0,js_nctips@0,js_widget_textinput@0,js_widget_sug@0,js_mp@0,js_hash_lib@0,js_skinRenderIndex@0,js_skinIphone@0,js_prefetch@0,js_sug@0,js_iscroll@0,js_superframe@0,js_init@0,js_geolocation@0,js_login@0,js_tab@0,js_md5@0,js_url@0,js_lswrite@0,js_modal@0,js_thirdparty@0,js_m_monitor@0,js_superstart@0,js_baiduloc@0,js_callbaiduapp_android@0&callback=B.getCode&r=248&sid=114551_143669_142112_140843_142507_143382_142210_143859_143879_139043_143162_143867_143424_142580_139178_143344_142779_131246_142909_137743_138165_141942_127969_142871_140066_142906_140593_143058_141807_138425_143469_143923_131423_144005_144087_138595_139883_143477_140312_138661_141103_110085"}]}},"uses-passive-event-listeners":{"id":"uses-passive-event-listeners","title":"使用被动式监听器来提高滚动性能","description":"建议您将触摸和滚轮事件监听器标记为 `passive`，以提高页面的滚动性能。[了解详情](https://web.dev/uses-passive-event-listeners)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"meta-description":{"id":"meta-description","title":"文档缺少 meta 描述","description":"元描述可能会被包含在搜索结果中，以简要概括网页内容。[了解详情](https://web.dev/meta-description)。","score":0,"scoreDisplayMode":"binary"},"http-status-code":{"id":"http-status-code","title":"页面返回了有效的 HTTP 状态代码","description":"返回无效 HTTP 状态代码的页面可能无法被正确编入索引。[了解详情](https://web.dev/http-status-code)。","score":1,"scoreDisplayMode":"binary"},"font-size":{"id":"font-size","title":"文档所用的字体大小清晰可辨","description":"12px 以下的字体过小，会导致用户无法辨认；此外，这样的字体需要移动设备访问者“张合双指进行缩放”才能阅读。请尽量让 60% 以上的页面文字不小于 12px。[了解详情](https://web.dev/font-size)。","score":1,"scoreDisplayMode":"binary","displayValue":"99.8% 清晰可辨的文字","details":{"type":"table","headings":[{"key":"source","itemType":"url","text":"Source"},{"key":"selector","itemType":"code","text":"Selector"},{"key":"coverage","itemType":"text","text":"% of Page Text"},{"key":"fontSize","itemType":"text","text":"Font Size"}],"items":[{"source":"dynamic","selector":".rn-typeSmallVideo .rn-wise-icon-pics","coverage":"0.12%","fontSize":"10px"},{"source":"dynamic","selector":".suggest-panel .sug-oper-btn","coverage":"0.08%","fontSize":"11px"},{"source":"Legible text","selector":"","coverage":"99.80%","fontSize":"≥ 12px"}]}},"link-text":{"id":"link-text","title":"链接有描述性文字","description":"描述性链接文字有助于搜索引擎理解您的内容。[了解详情](https://web.dev/link-text)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[],"summary":{}}},"is-crawlable":{"id":"is-crawlable","title":"页面已被屏蔽，无法编入索引","description":"如果搜索引擎无权抓取您的网页，则无法将它们添加到搜索结果中。[了解详情](https://web.dev/is-crawable)。","score":0,"scoreDisplayMode":"binary","details":{"type":"table","headings":[{"key":"source","itemType":"code","text":"Blocking Directive Source"}],"items":[{"source":{"type":"url","value":"https://www.baidu.com/robots.txt"}}]}},"robots-txt":{"id":"robots-txt","title":"robots.txt 有效","description":"如果 robots.txt 文件的格式不正确，抓取工具可能无法理解您希望以何种方式抓取网站内容或将其编入索引。[了解详情](https://web.dev/robots-txt)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[],"summary":{}}},"tap-targets":{"id":"tap-targets","title":"点按目标的大小不合适","description":"交互式元素（例如按钮和链接）应足够大 (48x48px)，且其周围应有足够的空间，以便用户轻松点按且避免遮挡其他元素。[了解详情](https://web.dev/tap-targets)。","score":0.72,"scoreDisplayMode":"binary","displayValue":"81% 的点按目标大小合适","details":{"type":"table","headings":[{"key":"tapTarget","itemType":"node","text":"点按目标"},{"key":"size","itemType":"text","text":"大小"},{"key":"overlappingTarget","itemType":"node","text":"点按目标重叠"}],"items":[{"tapTarget":{"type":"node","snippet":"\u003ca class=\"square-enterance\" data-tclog=\"\" href=\"https://m.baidu.com/l=1/tc?logid=2346015140&amp;from=844b&amp;ref=index_iphone&amp;nsrc=IlPT2AEptyoA_yixCFOxCGZb8c3JV3T5ABfPNy6R2iv5nk_qva02FMNsUiH5Nn_KJoCa9m3BdMZObmGcWyNnn1E2e_&amp;bdenc=1&amp;ct=10&amp;cst=2&amp;logFrom=navs_square\">\u003ci class=\"ns-ic…","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,0,DIV,2,A","selector":"div#index-card > div#header > div#userinfo-wrap > a.square-enterance","nodeLabel":"a"},"overlappingTarget":{"type":"node","snippet":"\u003ca data-tclog=\"{ct: 10, cst: 2, logFrom: usertext}\" class=\"index-banner    square-banner-bgicon  \" data-thunder=\"cst:2;tid:97;logFrom:user;logInfo:text;logExtra:{&quot;login&quot;:0};ref:index_iphone;url:https://m.baidu.com/s?word=100%25%E6%9E%9C%E6%B1%81%E5%85%91%E6%B0%B4%E5%90%97&amp;sa=searchpro…","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,0,DIV,0,DIV,0,A","selector":"div#header > div#userinfo-wrap > div#login-wraps > a.index-banner","nodeLabel":"a"},"tapTargetScore":380,"overlappingTargetScore":264,"overlapScoreRatio":0.6947368421052632,"size":"16x16","width":16,"height":16},{"tapTarget":{"type":"node","snippet":"\u003ca data-tclog=\"{ct: 10, cst: 2, logFrom: usertext}\" class=\"index-banner    square-banner-bgicon  \" data-thunder=\"cst:2;tid:97;logFrom:user;logInfo:text;logExtra:{&quot;login&quot;:0};ref:index_iphone;url:https://m.baidu.com/s?word=100%25%E6%9E%9C%E6%B1%81%E5%85%91%E6%B0%B4%E5%90%97&amp;sa=searchpro…","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,0,DIV,0,DIV,0,A","selector":"div#header > div#userinfo-wrap > div#login-wraps > a.index-banner","nodeLabel":"a"},"overlappingTarget":{"type":"node","snippet":"\u003ca href=\"https://m.baidu.com/s?word=%e4%bb%8a%e6%97%a5%e6%96%b0%e9%b2%9c%e4%ba%8b&amp;tn&amp;from=1020854c&amp;sa=tre_dl_gh_logo_wj\">\u003cimg src=\"https://m.baidu.com/static/index/plus/plus_logo_web.png\" alt=\"百度一下,你就知道\">\u003cscript type=\"text/javascript\">B.load(function () {require(['wiseindex/lib/ivk/logo…","path":"1,HTML,2,BODY,3,DIV,0,DIV,1,DIV,2,DIV,0,A","selector":"div#index-card > div#header > div#logo > a","nodeLabel":"百度一下,你就知道"},"tapTargetScore":1008,"overlappingTargetScore":696,"overlapScoreRatio":0.6904761904761905,"size":"154x22","width":154,"height":22},{"tapTarget":{"type":"node","snippet":"\u003ca id=\"index-copyright\" href=\"https://m.baidu.com/sf?pd=sd_privacy_terms&amp;ms=1&amp;ms=1&amp;word=%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E&amp;title=%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E&amp;openapi=1&amp;from_sf=1&amp;resource_id=37483&amp;dsp=iphone&amp;tn=wisexmlnew&amp;ext=%7B%22pid%22%3A%22mianze…","path":"1,HTML,2,BODY,3,DIV,0,DIV,8,DIV,0,DIV,1,A","selector":"div#index-card > div#bottom > div#foot > a#index-copyright","nodeLabel":"使用百度前必读 Baidu 京ICP证030173号"},"overlappingTarget":{"type":"node","snippet":"\u003ca href=\"http://ufosdk.baidu.com/?m=Client&amp;a=commonsubmit&amp;appid=517&amp;activityId=1&amp;needEmail=false&amp;bw=88C7BD6C60D47AD71CFBE516CB4A166B&amp;kw=&amp;tn=iphone&amp;pageid=6\" data-stats=\"10|2|foot|a1_b2\">\u003ci class=\"icon-feedback\">\u003c/i>用户反馈\u003c/a>","path":"1,HTML,2,BODY,3,DIV,0,DIV,8,DIV,0,DIV,0,DIV,0,A","selector":"div#bottom > div#foot > div > a","nodeLabel":"用户反馈"},"tapTargetScore":1248,"overlappingTargetScore":528,"overlapScoreRatio":0.4230769230769231,"size":"356x26","width":356,"height":26},{"tapTarget":{"type":"node","snippet":"\u003ca id=\"index-copyright\" href=\"https://m.baidu.com/sf?pd=sd_privacy_terms&amp;ms=1&amp;ms=1&amp;word=%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E&amp;title=%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E&amp;openapi=1&amp;from_sf=1&amp;resource_id=37483&amp;dsp=iphone&amp;tn=wisexmlnew&amp;ext=%7B%22pid%22%3A%22mianze…","path":"1,HTML,2,BODY,3,DIV,0,DIV,8,DIV,0,DIV,1,A","selector":"div#index-card > div#bottom > div#foot > a#index-copyright","nodeLabel":"使用百度前必读 Baidu 京ICP证030173号"},"overlappingTarget":{"type":"node","snippet":"\u003ca class=\"recordcode\" href=\"http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11000002000001\" target=\"_blank\">\u003ci>\u003c/i>京公网安备11000002000001号\u003c/a>","path":"1,HTML,2,BODY,3,DIV,0,DIV,8,DIV,0,DIV,2,A","selector":"div#index-card > div#bottom > div#foot > a.recordcode","nodeLabel":"京公网安备11000002000001号"},"tapTargetScore":1248,"overlappingTargetScore":528,"overlapScoreRatio":0.4230769230769231,"size":"356x26","width":356,"height":26}]}},"hreflang":{"id":"hreflang","title":"文档的 `hreflang` 有效","description":"hreflang 链接用于告知搜索引擎应在特定语言或地区的搜索结果中显示哪种版本的网页。[了解详情](https://web.dev/hreflang)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"plugins":{"id":"plugins","title":"文档中没有插件","description":"搜索引擎无法将插件内容编入索引，而且许多设备都限制或不支持使用插件。[了解详情](https://web.dev/plugins)。","score":1,"scoreDisplayMode":"binary","details":{"type":"table","headings":[],"items":[]}},"canonical":{"id":"canonical","title":"文档的 `rel=canonical` 有效","description":"规范链接用于建议应在搜索结果中显示哪个网址。[了解详情](https://web.dev/canonical)。","score":null,"scoreDisplayMode":"notApplicable"},"structured-data":{"id":"structured-data","title":"结构化数据有效","description":"运行[结构化数据测试工具](https://search.google.com/structured-data/testing-tool/) 和 [Structured Data Linter](http://linter.structured-data.org/) 可验证结构化数据。[了解详情](https://web.dev/structured-data)。","score":null,"scoreDisplayMode":"manual"}},"configSettings":{"output":["html"],"maxWaitForFcp":30000,"maxWaitForLoad":45000,"throttlingMethod":"simulate","throttling":{"rttMs":150,"throughputKbps":1638.4,"requestLatencyMs":562.5,"downloadThroughputKbps":1474.5600000000002,"uploadThroughputKbps":675,"cpuSlowdownMultiplier":4},"auditMode":false,"gatherMode":false,"disableStorageReset":false,"emulatedFormFactor":"mobile","channel":"cli","budgets":null,"locale":"zh","blockedUrlPatterns":null,"additionalTraceCategories":null,"extraHeaders":null,"precomputedLanternData":null,"onlyAudits":null,"onlyCategories":null,"skipAudits":null},"categories":{"performance":{"title":"性能","auditRefs":[{"id":"first-contentful-paint","weight":3,"group":"metrics"},{"id":"first-meaningful-paint","weight":1,"group":"metrics"},{"id":"speed-index","weight":4,"group":"metrics"},{"id":"interactive","weight":5,"group":"metrics"},{"id":"first-cpu-idle","weight":2,"group":"metrics"},{"id":"max-potential-fid","weight":0,"group":"metrics"},{"id":"estimated-input-latency","weight":0},{"id":"total-blocking-time","weight":0},{"id":"render-blocking-resources","weight":0,"group":"load-opportunities"},{"id":"uses-responsive-images","weight":0,"group":"load-opportunities"},{"id":"offscreen-images","weight":0,"group":"load-opportunities"},{"id":"unminified-css","weight":0,"group":"load-opportunities"},{"id":"unminified-javascript","weight":0,"group":"load-opportunities"},{"id":"unused-css-rules","weight":0,"group":"load-opportunities"},{"id":"uses-optimized-images","weight":0,"group":"load-opportunities"},{"id":"uses-webp-images","weight":0,"group":"load-opportunities"},{"id":"uses-text-compression","weight":0,"group":"load-opportunities"},{"id":"uses-rel-preconnect","weight":0,"group":"load-opportunities"},{"id":"time-to-first-byte","weight":0,"group":"load-opportunities"},{"id":"redirects","weight":0,"group":"load-opportunities"},{"id":"uses-rel-preload","weight":0,"group":"load-opportunities"},{"id":"efficient-animated-content","weight":0,"group":"load-opportunities"},{"id":"total-byte-weight","weight":0,"group":"diagnostics"},{"id":"uses-long-cache-ttl","weight":0,"group":"diagnostics"},{"id":"dom-size","weight":0,"group":"diagnostics"},{"id":"critical-request-chains","weight":0,"group":"diagnostics"},{"id":"user-timings","weight":0,"group":"diagnostics"},{"id":"bootup-time","weight":0,"group":"diagnostics"},{"id":"mainthread-work-breakdown","weight":0,"group":"diagnostics"},{"id":"font-display","weight":0,"group":"diagnostics"},{"id":"performance-budget","weight":0,"group":"budgets"},{"id":"resource-summary","weight":0,"group":"diagnostics"},{"id":"third-party-summary","weight":0,"group":"diagnostics"},{"id":"network-requests","weight":0},{"id":"network-rtt","weight":0},{"id":"network-server-latency","weight":0},{"id":"main-thread-tasks","weight":0},{"id":"diagnostics","weight":0},{"id":"metrics","weight":0},{"id":"screenshot-thumbnails","weight":0},{"id":"final-screenshot","weight":0}],"id":"performance","score":0.69},"accessibility":{"title":"无障碍","description":"这些检查会突出显示可[改进您网络应用的无障碍功能](https://developers.google.com/web/fundamentals/accessibility)的提示。系统只能自动检测到一小部分无障碍功能问题，因此您最好也手动测试一下。","manualDescription":"这些条目旨在检查自动化测试工具未涵盖的方面。如需了解详情，请参阅有关如何[执行无障碍功能审查](https://developers.google.com/web/fundamentals/accessibility/how-to-review)的指南。","auditRefs":[{"id":"accesskeys","weight":0,"group":"a11y-navigation"},{"id":"aria-allowed-attr","weight":0,"group":"a11y-aria"},{"id":"aria-required-attr","weight":0,"group":"a11y-aria"},{"id":"aria-required-children","weight":0,"group":"a11y-aria"},{"id":"aria-required-parent","weight":0,"group":"a11y-aria"},{"id":"aria-roles","weight":0,"group":"a11y-aria"},{"id":"aria-valid-attr-value","weight":0,"group":"a11y-aria"},{"id":"aria-valid-attr","weight":0,"group":"a11y-aria"},{"id":"audio-caption","weight":0,"group":"a11y-audio-video"},{"id":"button-name","weight":10,"group":"a11y-names-labels"},{"id":"bypass","weight":3,"group":"a11y-navigation"},{"id":"color-contrast","weight":3,"group":"a11y-color-contrast"},{"id":"definition-list","weight":0,"group":"a11y-tables-lists"},{"id":"dlitem","weight":0,"group":"a11y-tables-lists"},{"id":"document-title","weight":3,"group":"a11y-names-labels"},{"id":"duplicate-id","weight":1,"group":"a11y-best-practices"},{"id":"frame-title","weight":0,"group":"a11y-names-labels"},{"id":"html-has-lang","weight":3,"group":"a11y-language"},{"id":"html-lang-valid","weight":0,"group":"a11y-language"},{"id":"image-alt","weight":10,"group":"a11y-names-labels"},{"id":"input-image-alt","weight":0,"group":"a11y-names-labels"},{"id":"label","weight":10,"group":"a11y-names-labels"},{"id":"layout-table","weight":0,"group":"a11y-tables-lists"},{"id":"link-name","weight":3,"group":"a11y-names-labels"},{"id":"list","weight":3,"group":"a11y-tables-lists"},{"id":"listitem","weight":3,"group":"a11y-tables-lists"},{"id":"meta-refresh","weight":0,"group":"a11y-best-practices"},{"id":"meta-viewport","weight":10,"group":"a11y-best-practices"},{"id":"object-alt","weight":0,"group":"a11y-names-labels"},{"id":"tabindex","weight":0,"group":"a11y-navigation"},{"id":"td-headers-attr","weight":0,"group":"a11y-tables-lists"},{"id":"th-has-data-cells","weight":0,"group":"a11y-tables-lists"},{"id":"valid-lang","weight":0,"group":"a11y-language"},{"id":"video-caption","weight":0,"group":"a11y-audio-video"},{"id":"video-description","weight":0,"group":"a11y-audio-video"},{"id":"logical-tab-order","weight":0},{"id":"focusable-controls","weight":0},{"id":"interactive-element-affordance","weight":0},{"id":"managed-focus","weight":0},{"id":"focus-traps","weight":0},{"id":"custom-controls-labels","weight":0},{"id":"custom-controls-roles","weight":0},{"id":"visual-order-follows-dom","weight":0},{"id":"offscreen-content-hidden","weight":0},{"id":"heading-levels","weight":0},{"id":"use-landmarks","weight":0}],"id":"accessibility","score":0.32},"best-practices":{"title":"最佳做法","auditRefs":[{"id":"appcache-manifest","weight":1},{"id":"is-on-https","weight":1},{"id":"uses-http2","weight":1},{"id":"uses-passive-event-listeners","weight":1},{"id":"no-document-write","weight":1},{"id":"external-anchors-use-rel-noopener","weight":1},{"id":"geolocation-on-start","weight":1},{"id":"doctype","weight":1},{"id":"no-vulnerable-libraries","weight":1},{"id":"js-libraries","weight":0},{"id":"notification-on-start","weight":1},{"id":"deprecations","weight":1},{"id":"password-inputs-can-be-pasted-into","weight":1},{"id":"errors-in-console","weight":1},{"id":"image-aspect-ratio","weight":1}],"id":"best-practices","score":0.71},"seo":{"title":"SEO","description":"这些检查可确保您的页面已经过优化，有利于其在搜索引擎结果中的排名。不在 Lighthouse 检查范围内的其他因素可能会影响您的搜索排名。[了解详情](https://support.google.com/webmasters/answer/35769)。","manualDescription":"请在您的网站上运行这些额外的验证程序，以检查其他 SEO 最佳做法。","auditRefs":[{"id":"viewport","weight":1,"group":"seo-mobile"},{"id":"document-title","weight":1,"group":"seo-content"},{"id":"meta-description","weight":1,"group":"seo-content"},{"id":"http-status-code","weight":1,"group":"seo-crawl"},{"id":"link-text","weight":1,"group":"seo-content"},{"id":"is-crawlable","weight":1,"group":"seo-crawl"},{"id":"robots-txt","weight":1,"group":"seo-crawl"},{"id":"image-alt","weight":1,"group":"seo-content"},{"id":"hreflang","weight":1,"group":"seo-content"},{"id":"canonical","weight":0,"group":"seo-content"},{"id":"font-size","weight":1,"group":"seo-mobile"},{"id":"plugins","weight":1,"group":"seo-content"},{"id":"tap-targets","weight":1,"group":"seo-mobile"},{"id":"structured-data","weight":0}],"id":"seo","score":0.73},"pwa":{"title":"渐进式 Web 应用","description":"此类检查会验证渐进式 Web 应用的各个方面。[了解详情](https://developers.google.com/web/progressive-web-apps/checklist)。","manualDescription":"基准 [PWA 核对清单](https://developers.google.com/web/progressive-web-apps/checklist)要求必须进行此类检查，但 Lighthouse 不会自动进行此类检查。它们不会影响您的得分，但您必须手动对其进行验证。","auditRefs":[{"id":"load-fast-enough-for-pwa","weight":7,"group":"pwa-fast-reliable"},{"id":"works-offline","weight":5,"group":"pwa-fast-reliable"},{"id":"offline-start-url","weight":1,"group":"pwa-fast-reliable"},{"id":"is-on-https","weight":2,"group":"pwa-installable"},{"id":"service-worker","weight":1,"group":"pwa-installable"},{"id":"installable-manifest","weight":2,"group":"pwa-installable"},{"id":"redirects-http","weight":2,"group":"pwa-optimized"},{"id":"splash-screen","weight":1,"group":"pwa-optimized"},{"id":"themed-omnibox","weight":1,"group":"pwa-optimized"},{"id":"content-width","weight":1,"group":"pwa-optimized"},{"id":"viewport","weight":2,"group":"pwa-optimized"},{"id":"without-javascript","weight":1,"group":"pwa-optimized"},{"id":"apple-touch-icon","weight":1,"group":"pwa-optimized"},{"id":"pwa-cross-browser","weight":0},{"id":"pwa-page-transitions","weight":0},{"id":"pwa-each-page-has-url","weight":0}],"id":"pwa","score":0.44}},"categoryGroups":{"metrics":{"title":"指标"},"load-opportunities":{"title":"优化建议","description":"这些建议可以帮助您提高网页加载速度。它们不会[直接影响](https://github.com/GoogleChrome/lighthouse/blob/d2ec9ffbb21de9ad1a0f86ed24575eda32c796f0/docs/scoring.md#how-are-the-scores-weighted)性能得分。"},"budgets":{"title":"预算","description":"性能预算为您的网站的性能设置了标准。"},"diagnostics":{"title":"诊断结果","description":"详细了解您的应用的性能。这些数字不会[直接影响](https://github.com/GoogleChrome/lighthouse/blob/d2ec9ffbb21de9ad1a0f86ed24575eda32c796f0/docs/scoring.md#how-are-the-scores-weighted)性能得分。"},"pwa-fast-reliable":{"title":"快速且可靠"},"pwa-installable":{"title":"可安装"},"pwa-optimized":{"title":"优化 PWA"},"a11y-best-practices":{"title":"最佳做法","description":"这些条目突出显示了常见的无障碍功能最佳做法。"},"a11y-color-contrast":{"title":"对比度","description":"这些提示旨在帮助改进您的内容的易读性。"},"a11y-names-labels":{"title":"名称和标签","description":"这些提示旨在帮助改进您的应用内控件的语义。这可以改善辅助技术（例如屏幕阅读器）用户的体验。"},"a11y-navigation":{"title":"导航","description":"这些提示旨在改进您应用中的键盘导航。"},"a11y-aria":{"title":"ARIA","description":"这些提示旨在帮助改进 ARIA 在您的应用内的使用情况，从而改善辅助技术（例如屏幕阅读器）用户的体验。"},"a11y-language":{"title":"国际化和本地化","description":"这些提示旨在让不同语言区域中的用户能够更好地解读您的内容。"},"a11y-audio-video":{"title":"音频和视频","description":"这提示旨在为音频和视频提供替代内容。这或许能改善听障用户或视障用户的体验。"},"a11y-tables-lists":{"title":"表格和列表","description":"这些提示旨在改善使用辅助技术（例如屏幕阅读器）查看表格数据或列表数据的体验。"},"seo-mobile":{"title":"适合移动设备","description":"请确保您的网页适合移动设备，以便用户无需进行缩放即可轻松阅读内容页面。[了解详情](https://developers.google.com/search/mobile-sites/)。"},"seo-content":{"title":"内容最佳做法","description":"请确保您的 HTML 格式正确，以便抓取工具更好地了解您的应用的内容。"},"seo-crawl":{"title":"抓取和编入索引","description":"若想让您的应用显示在搜索结果中，您需要先授权抓取工具访问该应用。"}},"timing":{"entries":[{"startTime":1159.18,"name":"lh:init:config","duration":230.44,"entryType":"measure"},{"startTime":1161.82,"name":"lh:config:requireGatherers","duration":40.91,"entryType":"measure"},{"startTime":1202.89,"name":"lh:config:requireAudits","duration":175.31,"entryType":"measure"},{"startTime":1390.06,"name":"lh:runner:run","duration":7754.04,"entryType":"measure"},{"startTime":1391.19,"name":"lh:init:connect","duration":15.12,"entryType":"measure"},{"startTime":1406.37,"name":"lh:gather:loadBlank","duration":69.43,"entryType":"measure"},{"startTime":1475.93,"name":"lh:gather:getVersion","duration":0.63,"entryType":"measure"},{"startTime":1476.67,"name":"lh:gather:getBenchmarkIndex","duration":503.75,"entryType":"measure"},{"startTime":1980.55,"name":"lh:gather:setupDriver","duration":22.88,"entryType":"measure"},{"startTime":2003.59,"name":"lh:gather:loadBlank","duration":7.27,"entryType":"measure"},{"startTime":2010.98,"name":"lh:gather:setupPassNetwork","duration":1.4,"entryType":"measure"},{"startTime":2012.45,"name":"lh:driver:cleanBrowserCaches","duration":18.78,"entryType":"measure"},{"startTime":2031.41,"name":"lh:gather:beforePass","duration":3.48,"entryType":"measure"},{"startTime":2031.47,"name":"lh:gather:beforePass:CSSUsage","duration":0.07,"entryType":"measure"},{"startTime":2031.57,"name":"lh:gather:beforePass:ViewportDimensions","duration":0.02,"entryType":"measure"},{"startTime":2031.6,"name":"lh:gather:beforePass:RuntimeExceptions","duration":0.05,"entryType":"measure"},{"startTime":2031.65,"name":"lh:gather:beforePass:ConsoleMessages","duration":2.08,"entryType":"measure"},{"startTime":2033.75,"name":"lh:gather:beforePass:AnchorElements","duration":0.02,"entryType":"measure"},{"startTime":2033.78,"name":"lh:gather:beforePass:ImageElements","duration":0.01,"entryType":"measure"},{"startTime":2033.8,"name":"lh:gather:beforePass:LinkElements","duration":0.01,"entryType":"measure"},{"startTime":2033.81,"name":"lh:gather:beforePass:MetaElements","duration":0.01,"entryType":"measure"},{"startTime":2033.83,"name":"lh:gather:beforePass:ScriptElements","duration":0.01,"entryType":"measure"},{"startTime":2033.84,"name":"lh:gather:beforePass:IFrameElements","duration":0.01,"entryType":"measure"},{"startTime":2033.85,"name":"lh:gather:beforePass:MainDocumentContent","duration":0.01,"entryType":"measure"},{"startTime":2033.86,"name":"lh:gather:beforePass:AppCacheManifest","duration":0.01,"entryType":"measure"},{"startTime":2033.87,"name":"lh:gather:beforePass:Doctype","duration":0.01,"entryType":"measure"},{"startTime":2033.88,"name":"lh:gather:beforePass:DOMStats","duration":0.01,"entryType":"measure"},{"startTime":2033.89,"name":"lh:gather:beforePass:OptimizedImages","duration":0.01,"entryType":"measure"},{"startTime":2033.9,"name":"lh:gather:beforePass:PasswordInputsWithPreventedPaste","duration":0.01,"entryType":"measure"},{"startTime":2033.91,"name":"lh:gather:beforePass:ResponseCompression","duration":0.01,"entryType":"measure"},{"startTime":2033.92,"name":"lh:gather:beforePass:TagsBlockingFirstPaint","duration":0.9,"entryType":"measure"},{"startTime":2034.83,"name":"lh:gather:beforePass:FontSize","duration":0.02,"entryType":"measure"},{"startTime":2034.85,"name":"lh:gather:beforePass:EmbeddedContent","duration":0.01,"entryType":"measure"},{"startTime":2034.86,"name":"lh:gather:beforePass:RobotsTxt","duration":0.01,"entryType":"measure"},{"startTime":2034.87,"name":"lh:gather:beforePass:TapTargets","duration":0.01,"entryType":"measure"},{"startTime":2034.88,"name":"lh:gather:beforePass:Accessibility","duration":0.01,"entryType":"measure"},{"startTime":2034.98,"name":"lh:gather:beginRecording","duration":55.88,"entryType":"measure"},{"startTime":2035.24,"name":"lh:gather:getVersion","duration":0.43,"entryType":"measure"},{"startTime":2091.16,"name":"lh:gather:loadPage-defaultPass","duration":4154.43,"entryType":"measure"},{"startTime":6245.87,"name":"lh:gather:pass","duration":2.59,"entryType":"measure"},{"startTime":6248.67,"name":"lh:gather:getTrace","duration":163.64,"entryType":"measure"},{"startTime":6412.32,"name":"lh:gather:getDevtoolsLog","duration":3.15,"entryType":"measure"},{"startTime":6417.13,"name":"lh:gather:afterPass","duration":997.2,"entryType":"measure"},{"startTime":6422.29,"name":"lh:gather:afterPass:CSSUsage","duration":55.6,"entryType":"measure"},{"startTime":6477.92,"name":"lh:gather:afterPass:ViewportDimensions","duration":2.98,"entryType":"measure"},{"startTime":6480.92,"name":"lh:gather:afterPass:RuntimeExceptions","duration":1.44,"entryType":"measure"},{"startTime":6482.37,"name":"lh:gather:afterPass:ConsoleMessages","duration":2.92,"entryType":"measure"},{"startTime":6485.31,"name":"lh:gather:afterPass:AnchorElements","duration":6.42,"entryType":"measure"},{"startTime":6491.74,"name":"lh:gather:afterPass:ImageElements","duration":40.84,"entryType":"measure"},{"startTime":6532.6,"name":"lh:gather:afterPass:LinkElements","duration":3.39,"entryType":"measure"},{"startTime":6536.01,"name":"lh:gather:afterPass:MetaElements","duration":2.61,"entryType":"measure"},{"startTime":6538.63,"name":"lh:gather:afterPass:ScriptElements","duration":63.47,"entryType":"measure"},{"startTime":6602.12,"name":"lh:gather:afterPass:IFrameElements","duration":2.48,"entryType":"measure"},{"startTime":6604.61,"name":"lh:gather:afterPass:MainDocumentContent","duration":5.81,"entryType":"measure"},{"startTime":6610.43,"name":"lh:gather:afterPass:AppCacheManifest","duration":4.61,"entryType":"measure"},{"startTime":6615.05,"name":"lh:gather:afterPass:Doctype","duration":2.3,"entryType":"measure"},{"startTime":6617.37,"name":"lh:gather:afterPass:DOMStats","duration":5.2,"entryType":"measure"},{"startTime":6622.58,"name":"lh:gather:afterPass:OptimizedImages","duration":224.87,"entryType":"measure"},{"startTime":6847.46,"name":"lh:gather:afterPass:PasswordInputsWithPreventedPaste","duration":3.1,"entryType":"measure"},{"startTime":6850.58,"name":"lh:gather:afterPass:ResponseCompression","duration":5.4,"entryType":"measure"},{"startTime":6855.98,"name":"lh:gather:afterPass:TagsBlockingFirstPaint","duration":3.6,"entryType":"measure"},{"startTime":6859.59,"name":"lh:gather:afterPass:FontSize","duration":151,"entryType":"measure"},{"startTime":7010.61,"name":"lh:gather:afterPass:EmbeddedContent","duration":3.84,"entryType":"measure"},{"startTime":7014.46,"name":"lh:gather:afterPass:RobotsTxt","duration":36.72,"entryType":"measure"},{"startTime":7051.2,"name":"lh:gather:afterPass:TapTargets","duration":30.22,"entryType":"measure"},{"startTime":7081.44,"name":"lh:gather:afterPass:Accessibility","duration":332.88,"entryType":"measure"},{"startTime":7496.24,"name":"lh:gather:loadBlank","duration":9.9,"entryType":"measure"},{"startTime":7506.16,"name":"lh:gather:setupPassNetwork","duration":1.6,"entryType":"measure"},{"startTime":7507.78,"name":"lh:gather:beforePass","duration":3.73,"entryType":"measure"},{"startTime":7507.8,"name":"lh:gather:beforePass:ServiceWorker","duration":2.59,"entryType":"measure"},{"startTime":7510.41,"name":"lh:gather:beforePass:Offline","duration":1.07,"entryType":"measure"},{"startTime":7511.49,"name":"lh:gather:beforePass:StartUrl","duration":0.02,"entryType":"measure"},{"startTime":7511.53,"name":"lh:gather:beginRecording","duration":0.08,"entryType":"measure"},{"startTime":7511.64,"name":"lh:gather:loadPage-offlinePass","duration":80.1,"entryType":"measure"},{"startTime":7591.77,"name":"lh:gather:pass","duration":0.18,"entryType":"measure"},{"startTime":7591.96,"name":"lh:gather:getDevtoolsLog","duration":0.12,"entryType":"measure"},{"startTime":7593.42,"name":"lh:gather:afterPass","duration":11.7,"entryType":"measure"},{"startTime":7598.75,"name":"lh:gather:afterPass:ServiceWorker","duration":1.5,"entryType":"measure"},{"startTime":7600.26,"name":"lh:gather:afterPass:Offline","duration":1.59,"entryType":"measure"},{"startTime":7601.87,"name":"lh:gather:afterPass:StartUrl","duration":3.24,"entryType":"measure"},{"startTime":7605.17,"name":"lh:gather:loadBlank","duration":83.93,"entryType":"measure"},{"startTime":7689.11,"name":"lh:gather:setupPassNetwork","duration":3.19,"entryType":"measure"},{"startTime":7692.31,"name":"lh:gather:beforePass","duration":0.32,"entryType":"measure"},{"startTime":7692.33,"name":"lh:gather:beforePass:HTTPRedirect","duration":0.23,"entryType":"measure"},{"startTime":7692.57,"name":"lh:gather:beforePass:HTMLWithoutJavaScript","duration":0.05,"entryType":"measure"},{"startTime":7692.63,"name":"lh:gather:beginRecording","duration":0.1,"entryType":"measure"},{"startTime":7692.75,"name":"lh:gather:loadPage-redirectPass","duration":356.17,"entryType":"measure"},{"startTime":8048.94,"name":"lh:gather:pass","duration":0.11,"entryType":"measure"},{"startTime":8049.06,"name":"lh:gather:getDevtoolsLog","duration":0.5,"entryType":"measure"},{"startTime":8133.4,"name":"lh:gather:afterPass","duration":85.5,"entryType":"measure"},{"startTime":8214.34,"name":"lh:gather:afterPass:HTTPRedirect","duration":2.02,"entryType":"measure"},{"startTime":8216.37,"name":"lh:gather:afterPass:HTMLWithoutJavaScript","duration":2.52,"entryType":"measure"},{"startTime":8219.03,"name":"lh:gather:disconnect","duration":20.92,"entryType":"measure"},{"startTime":8240.3,"name":"lh:runner:auditing","duration":902.8,"entryType":"measure"},{"startTime":8247.17,"name":"lh:audit:is-on-https","duration":5.68,"entryType":"measure"},{"startTime":8247.55,"name":"lh:computed:NetworkRecords","duration":4.19,"entryType":"measure"},{"startTime":8253.35,"name":"lh:audit:redirects-http","duration":0.82,"entryType":"measure"},{"startTime":8254.36,"name":"lh:audit:service-worker","duration":0.36,"entryType":"measure"},{"startTime":8254.91,"name":"lh:audit:works-offline","duration":0.31,"entryType":"measure"},{"startTime":8255.4,"name":"lh:audit:viewport","duration":0.93,"entryType":"measure"},{"startTime":8255.57,"name":"lh:computed:ViewportMeta","duration":0.64,"entryType":"measure"},{"startTime":8256.51,"name":"lh:audit:without-javascript","duration":0.26,"entryType":"measure"},{"startTime":8256.92,"name":"lh:audit:first-contentful-paint","duration":34.35,"entryType":"measure"},{"startTime":8257.13,"name":"lh:computed:FirstContentfulPaint","duration":33.82,"entryType":"measure"},{"startTime":8257.25,"name":"lh:computed:TraceOfTab","duration":23.07,"entryType":"measure"},{"startTime":8280.43,"name":"lh:computed:LanternFirstContentfulPaint","duration":10.52,"entryType":"measure"},{"startTime":8280.61,"name":"lh:computed:PageDependencyGraph","duration":3.54,"entryType":"measure"},{"startTime":8284.18,"name":"lh:computed:LoadSimulator","duration":2.06,"entryType":"measure"},{"startTime":8284.27,"name":"lh:computed:NetworkAnalysis","duration":1.75,"entryType":"measure"},{"startTime":8291.45,"name":"lh:audit:first-meaningful-paint","duration":4.71,"entryType":"measure"},{"startTime":8291.72,"name":"lh:computed:FirstMeaningfulPaint","duration":4.2,"entryType":"measure"},{"startTime":8291.78,"name":"lh:computed:LanternFirstMeaningfulPaint","duration":4.13,"entryType":"measure"},{"startTime":8296.39,"name":"lh:audit:load-fast-enough-for-pwa","duration":16.54,"entryType":"measure"},{"startTime":8296.72,"name":"lh:computed:Interactive","duration":16.05,"entryType":"measure"},{"startTime":8296.77,"name":"lh:computed:LanternInteractive","duration":15.99,"entryType":"measure"},{"startTime":8313.21,"name":"lh:audit:speed-index","duration":352.41,"entryType":"measure"},{"startTime":8313.57,"name":"lh:computed:SpeedIndex","duration":351.85,"entryType":"measure"},{"startTime":8313.62,"name":"lh:computed:LanternSpeedIndex","duration":351.8,"entryType":"measure"},{"startTime":8313.79,"name":"lh:computed:Speedline","duration":329.68,"entryType":"measure"},{"startTime":8665.63,"name":"lh:audit:screenshot-thumbnails","duration":193.32,"entryType":"measure"},{"startTime":8858.97,"name":"lh:audit:final-screenshot","duration":0.95,"entryType":"measure"},{"startTime":8859.21,"name":"lh:computed:Screenshots","duration":0.67,"entryType":"measure"},{"startTime":8860.37,"name":"lh:audit:estimated-input-latency","duration":6.83,"entryType":"measure"},{"startTime":8860.55,"name":"lh:computed:EstimatedInputLatency","duration":6.4,"entryType":"measure"},{"startTime":8860.6,"name":"lh:computed:LanternEstimatedInputLatency","duration":6.35,"entryType":"measure"},{"startTime":8867.43,"name":"lh:audit:total-blocking-time","duration":7.65,"entryType":"measure"},{"startTime":8867.63,"name":"lh:computed:TotalBlockingTime","duration":7.23,"entryType":"measure"},{"startTime":8867.67,"name":"lh:computed:LanternTotalBlockingTime","duration":7.18,"entryType":"measure"},{"startTime":8875.38,"name":"lh:audit:max-potential-fid","duration":9.78,"entryType":"measure"},{"startTime":8875.79,"name":"lh:computed:MaxPotentialFID","duration":9.2,"entryType":"measure"},{"startTime":8875.83,"name":"lh:computed:LanternMaxPotentialFID","duration":9.15,"entryType":"measure"},{"startTime":8885.35,"name":"lh:audit:errors-in-console","duration":0.47,"entryType":"measure"},{"startTime":8886.02,"name":"lh:audit:time-to-first-byte","duration":0.56,"entryType":"measure"},{"startTime":8886.21,"name":"lh:computed:MainResource","duration":0.18,"entryType":"measure"},{"startTime":8886.71,"name":"lh:audit:first-cpu-idle","duration":3.73,"entryType":"measure"},{"startTime":8886.87,"name":"lh:computed:FirstCPUIdle","duration":3.44,"entryType":"measure"},{"startTime":8886.91,"name":"lh:computed:LanternFirstCPUIdle","duration":3.39,"entryType":"measure"},{"startTime":8890.58,"name":"lh:audit:interactive","duration":0.42,"entryType":"measure"},{"startTime":8891.16,"name":"lh:audit:user-timings","duration":1.18,"entryType":"measure"},{"startTime":8891.31,"name":"lh:computed:UserTimings","duration":0.81,"entryType":"measure"},{"startTime":8892.49,"name":"lh:audit:critical-request-chains","duration":1.51,"entryType":"measure"},{"startTime":8892.64,"name":"lh:computed:CriticalRequestChains","duration":0.64,"entryType":"measure"},{"startTime":8894.17,"name":"lh:audit:redirects","duration":0.55,"entryType":"measure"},{"startTime":8894.89,"name":"lh:audit:installable-manifest","duration":0.52,"entryType":"measure"},{"startTime":8895.09,"name":"lh:computed:ManifestValues","duration":0.06,"entryType":"measure"},{"startTime":8895.55,"name":"lh:audit:apple-touch-icon","duration":0.29,"entryType":"measure"},{"startTime":8896.07,"name":"lh:audit:splash-screen","duration":0.3,"entryType":"measure"},{"startTime":8896.53,"name":"lh:audit:themed-omnibox","duration":0.34,"entryType":"measure"},{"startTime":8897.06,"name":"lh:audit:content-width","duration":0.24,"entryType":"measure"},{"startTime":8897.45,"name":"lh:audit:image-aspect-ratio","duration":0.65,"entryType":"measure"},{"startTime":8898.25,"name":"lh:audit:deprecations","duration":0.32,"entryType":"measure"},{"startTime":8898.72,"name":"lh:audit:mainthread-work-breakdown","duration":11.65,"entryType":"measure"},{"startTime":8898.98,"name":"lh:computed:MainThreadTasks","duration":9.73,"entryType":"measure"},{"startTime":8910.6,"name":"lh:audit:bootup-time","duration":3.25,"entryType":"measure"},{"startTime":8914.08,"name":"lh:audit:uses-rel-preload","duration":1.63,"entryType":"measure"},{"startTime":8914.48,"name":"lh:computed:LoadSimulator","duration":0.11,"entryType":"measure"},{"startTime":8915.89,"name":"lh:audit:uses-rel-preconnect","duration":0.77,"entryType":"measure"},{"startTime":8916.82,"name":"lh:audit:font-display","duration":3.27,"entryType":"measure"},{"startTime":8920.1,"name":"lh:audit:diagnostics","duration":0.96,"entryType":"measure"},{"startTime":8921.07,"name":"lh:audit:network-requests","duration":1.09,"entryType":"measure"},{"startTime":8922.32,"name":"lh:audit:network-rtt","duration":0.41,"entryType":"measure"},{"startTime":8922.91,"name":"lh:audit:network-server-latency","duration":0.51,"entryType":"measure"},{"startTime":8923.44,"name":"lh:audit:main-thread-tasks","duration":0.32,"entryType":"measure"},{"startTime":8923.78,"name":"lh:audit:metrics","duration":1.03,"entryType":"measure"},{"startTime":8924.13,"name":"lh:computed:LargestContentfulPaint","duration":0.13,"entryType":"measure"},{"startTime":8925.06,"name":"lh:audit:offline-start-url","duration":0.31,"entryType":"measure"},{"startTime":8925.5,"name":"lh:audit:performance-budget","duration":2.1,"entryType":"measure"},{"startTime":8925.68,"name":"lh:computed:ResourceSummary","duration":1.77,"entryType":"measure"},{"startTime":8927.91,"name":"lh:audit:resource-summary","duration":1.16,"entryType":"measure"},{"startTime":8929.25,"name":"lh:audit:third-party-summary","duration":27.56,"entryType":"measure"},{"startTime":8957,"name":"lh:audit:pwa-cross-browser","duration":0.2,"entryType":"measure"},{"startTime":8957.4,"name":"lh:audit:pwa-page-transitions","duration":0.13,"entryType":"measure"},{"startTime":8957.66,"name":"lh:audit:pwa-each-page-has-url","duration":0.18,"entryType":"measure"},{"startTime":8958,"name":"lh:audit:accesskeys","duration":0.29,"entryType":"measure"},{"startTime":8958.44,"name":"lh:audit:aria-allowed-attr","duration":0.71,"entryType":"measure"},{"startTime":8959.33,"name":"lh:audit:aria-required-attr","duration":0.44,"entryType":"measure"},{"startTime":8960,"name":"lh:audit:aria-required-children","duration":0.26,"entryType":"measure"},{"startTime":8960.41,"name":"lh:audit:aria-required-parent","duration":0.27,"entryType":"measure"},{"startTime":8960.87,"name":"lh:audit:aria-roles","duration":0.28,"entryType":"measure"},{"startTime":8961.29,"name":"lh:audit:aria-valid-attr-value","duration":0.29,"entryType":"measure"},{"startTime":8961.75,"name":"lh:audit:aria-valid-attr","duration":0.31,"entryType":"measure"},{"startTime":8962.22,"name":"lh:audit:audio-caption","duration":0.31,"entryType":"measure"},{"startTime":8962.67,"name":"lh:audit:button-name","duration":0.73,"entryType":"measure"},{"startTime":8963.57,"name":"lh:audit:bypass","duration":1.01,"entryType":"measure"},{"startTime":8964.77,"name":"lh:audit:color-contrast","duration":0.52,"entryType":"measure"},{"startTime":8965.47,"name":"lh:audit:definition-list","duration":0.25,"entryType":"measure"},{"startTime":8965.91,"name":"lh:audit:dlitem","duration":0.26,"entryType":"measure"},{"startTime":8966.3,"name":"lh:audit:document-title","duration":0.51,"entryType":"measure"},{"startTime":8966.95,"name":"lh:audit:duplicate-id","duration":0.5,"entryType":"measure"},{"startTime":8967.59,"name":"lh:audit:frame-title","duration":0.33,"entryType":"measure"},{"startTime":8968.06,"name":"lh:audit:html-has-lang","duration":0.48,"entryType":"measure"},{"startTime":8968.69,"name":"lh:audit:html-lang-valid","duration":0.35,"entryType":"measure"},{"startTime":8969.18,"name":"lh:audit:image-alt","duration":0.49,"entryType":"measure"},{"startTime":8969.94,"name":"lh:audit:input-image-alt","duration":0.35,"entryType":"measure"},{"startTime":8970.43,"name":"lh:audit:label","duration":0.55,"entryType":"measure"},{"startTime":8971.15,"name":"lh:audit:layout-table","duration":0.31,"entryType":"measure"},{"startTime":8971.59,"name":"lh:audit:link-name","duration":0.54,"entryType":"measure"},{"startTime":8972.31,"name":"lh:audit:list","duration":0.55,"entryType":"measure"},{"startTime":8973.02,"name":"lh:audit:listitem","duration":0.51,"entryType":"measure"},{"startTime":8973.67,"name":"lh:audit:meta-refresh","duration":0.41,"entryType":"measure"},{"startTime":8974.27,"name":"lh:audit:meta-viewport","duration":0.56,"entryType":"measure"},{"startTime":8974.97,"name":"lh:audit:object-alt","duration":0.37,"entryType":"measure"},{"startTime":8975.7,"name":"lh:audit:tabindex","duration":0.44,"entryType":"measure"},{"startTime":8976.45,"name":"lh:audit:td-headers-attr","duration":0.58,"entryType":"measure"},{"startTime":8977.23,"name":"lh:audit:th-has-data-cells","duration":0.53,"entryType":"measure"},{"startTime":8977.94,"name":"lh:audit:valid-lang","duration":0.59,"entryType":"measure"},{"startTime":8978.94,"name":"lh:audit:video-caption","duration":0.48,"entryType":"measure"},{"startTime":8979.58,"name":"lh:audit:video-description","duration":0.47,"entryType":"measure"},{"startTime":8980.07,"name":"lh:audit:custom-controls-labels","duration":0.05,"entryType":"measure"},{"startTime":8980.13,"name":"lh:audit:custom-controls-roles","duration":0.04,"entryType":"measure"},{"startTime":8980.18,"name":"lh:audit:focus-traps","duration":0.03,"entryType":"measure"},{"startTime":8980.22,"name":"lh:audit:focusable-controls","duration":0.03,"entryType":"measure"},{"startTime":8980.26,"name":"lh:audit:heading-levels","duration":0.03,"entryType":"measure"},{"startTime":8980.3,"name":"lh:audit:interactive-element-affordance","duration":0.03,"entryType":"measure"},{"startTime":8980.33,"name":"lh:audit:logical-tab-order","duration":0.03,"entryType":"measure"},{"startTime":8980.37,"name":"lh:audit:managed-focus","duration":0.03,"entryType":"measure"},{"startTime":8980.41,"name":"lh:audit:offscreen-content-hidden","duration":0.03,"entryType":"measure"},{"startTime":8980.45,"name":"lh:audit:use-landmarks","duration":0.03,"entryType":"measure"},{"startTime":8980.48,"name":"lh:audit:visual-order-follows-dom","duration":0.03,"entryType":"measure"},{"startTime":8980.76,"name":"lh:audit:uses-long-cache-ttl","duration":3.02,"entryType":"measure"},{"startTime":8983.94,"name":"lh:audit:total-byte-weight","duration":0.52,"entryType":"measure"},{"startTime":8984.59,"name":"lh:audit:offscreen-images","duration":7.14,"entryType":"measure"},{"startTime":8991.94,"name":"lh:audit:render-blocking-resources","duration":5.65,"entryType":"measure"},{"startTime":8996.58,"name":"lh:computed:FirstContentfulPaint","duration":0.81,"entryType":"measure"},{"startTime":8996.63,"name":"lh:computed:LanternFirstContentfulPaint","duration":0.76,"entryType":"measure"},{"startTime":8997.79,"name":"lh:audit:unminified-css","duration":33,"entryType":"measure"},{"startTime":9030.98,"name":"lh:audit:unminified-javascript","duration":67.93,"entryType":"measure"},{"startTime":9099.08,"name":"lh:audit:unused-css-rules","duration":5.12,"entryType":"measure"},{"startTime":9104.4,"name":"lh:audit:uses-webp-images","duration":3.03,"entryType":"measure"},{"startTime":9108.09,"name":"lh:audit:uses-optimized-images","duration":3.16,"entryType":"measure"},{"startTime":9111.44,"name":"lh:audit:uses-text-compression","duration":4.73,"entryType":"measure"},{"startTime":9116.48,"name":"lh:audit:uses-responsive-images","duration":3.06,"entryType":"measure"},{"startTime":9119.71,"name":"lh:audit:efficient-animated-content","duration":2.76,"entryType":"measure"},{"startTime":9122.66,"name":"lh:audit:appcache-manifest","duration":0.25,"entryType":"measure"},{"startTime":9123.24,"name":"lh:audit:doctype","duration":0.39,"entryType":"measure"},{"startTime":9123.78,"name":"lh:audit:dom-size","duration":0.68,"entryType":"measure"},{"startTime":9124.66,"name":"lh:audit:external-anchors-use-rel-noopener","duration":0.47,"entryType":"measure"},{"startTime":9125.29,"name":"lh:audit:geolocation-on-start","duration":0.35,"entryType":"measure"},{"startTime":9125.76,"name":"lh:audit:no-document-write","duration":0.44,"entryType":"measure"},{"startTime":9126.54,"name":"lh:audit:no-vulnerable-libraries","duration":4.24,"entryType":"measure"},{"startTime":9130.99,"name":"lh:audit:js-libraries","duration":0.28,"entryType":"measure"},{"startTime":9131.43,"name":"lh:audit:notification-on-start","duration":0.24,"entryType":"measure"},{"startTime":9131.81,"name":"lh:audit:password-inputs-can-be-pasted-into","duration":0.23,"entryType":"measure"},{"startTime":9132.18,"name":"lh:audit:uses-http2","duration":0.92,"entryType":"measure"},{"startTime":9133.28,"name":"lh:audit:uses-passive-event-listeners","duration":0.26,"entryType":"measure"},{"startTime":9133.69,"name":"lh:audit:meta-description","duration":0.24,"entryType":"measure"},{"startTime":9134.07,"name":"lh:audit:http-status-code","duration":0.34,"entryType":"measure"},{"startTime":9134.56,"name":"lh:audit:font-size","duration":0.71,"entryType":"measure"},{"startTime":9135.43,"name":"lh:audit:link-text","duration":0.65,"entryType":"measure"},{"startTime":9136.35,"name":"lh:audit:is-crawlable","duration":1.69,"entryType":"measure"},{"startTime":9138.19,"name":"lh:audit:robots-txt","duration":0.68,"entryType":"measure"},{"startTime":9139.03,"name":"lh:audit:tap-targets","duration":2.15,"entryType":"measure"},{"startTime":9141.37,"name":"lh:audit:hreflang","duration":0.28,"entryType":"measure"},{"startTime":9141.79,"name":"lh:audit:plugins","duration":0.26,"entryType":"measure"},{"startTime":9142.2,"name":"lh:audit:canonical","duration":0.55,"entryType":"measure"},{"startTime":9142.94,"name":"lh:audit:structured-data","duration":0.14,"entryType":"measure"},{"startTime":9143.13,"name":"lh:runner:generate","duration":0.97,"entryType":"measure"}],"total":7754.04},"i18n":{"rendererFormattedStrings":{"auditGroupExpandTooltip":"显示审核结果","crcInitialNavigation":"初始导航","crcLongestDurationLabel":"关键路径延迟时间上限：","errorLabel":"出错了！","errorMissingAuditInfo":"报告错误：没有任何审核信息","labDataTitle":"实验室数据","lsPerformanceCategoryDescription":"[Lighthouse](https://developers.google.com/web/tools/lighthouse/) 使用模拟的移动网络对当前页面进行的分析。这些值都是估算值，且可能会因时而异。","manualAuditsGroupTitle":"待手动检查的其他项","notApplicableAuditsGroupTitle":"不适用","opportunityResourceColumnLabel":"优化建议","opportunitySavingsColumnLabel":"有望节省的总时间（估算值）","passedAuditsGroupTitle":"已通过的审核","snippetCollapseButtonLabel":"收起代码段","snippetExpandButtonLabel":"展开代码段","thirdPartyResourcesLabel":"显示第三方资源","toplevelWarningsMessage":"此次 Lighthouse 运行并不顺利，原因如下：","varianceDisclaimer":"这些值都是估算值，且可能会因时而异。性能得分[仅基于这些指标](https://github.com/GoogleChrome/lighthouse/blob/d2ec9ffbb21de9ad1a0f86ed24575eda32c796f0/docs/scoring.md#how-are-the-scores-weighted)。","warningAuditsGroupTitle":"已顺利通过审核，但有警告消息","warningHeader":"警告： "},"icuMessagePaths":{"lighthouse-core/audits/is-on-https.js | failureTitle":["audits[is-on-https].title"],"lighthouse-core/audits/is-on-https.js | description":["audits[is-on-https].description"],"lighthouse-core/audits/is-on-https.js | displayValue":[{"values":{"itemCount":2},"path":"audits[is-on-https].displayValue"}],"lighthouse-core/audits/is-on-https.js | columnInsecureURL":["audits[is-on-https].details.headings[0].text"],"lighthouse-core/audits/redirects-http.js | failureTitle":["audits[redirects-http].title"],"lighthouse-core/audits/redirects-http.js | description":["audits[redirects-http].description"],"lighthouse-core/audits/service-worker.js | failureTitle":["audits[service-worker].title"],"lighthouse-core/audits/service-worker.js | description":["audits[service-worker].description"],"lighthouse-core/audits/works-offline.js | failureTitle":["audits[works-offline].title"],"lighthouse-core/audits/works-offline.js | description":["audits[works-offline].description"],"lighthouse-core/audits/viewport.js | title":["audits.viewport.title"],"lighthouse-core/audits/viewport.js | description":["audits.viewport.description"],"lighthouse-core/audits/without-javascript.js | title":["audits[without-javascript].title"],"lighthouse-core/audits/without-javascript.js | description":["audits[without-javascript].description"],"lighthouse-core/audits/metrics/first-contentful-paint.js | title":["audits[first-contentful-paint].title"],"lighthouse-core/audits/metrics/first-contentful-paint.js | description":["audits[first-contentful-paint].description"],"lighthouse-core/lib/i18n/i18n.js | seconds":[{"values":{"timeInMs":1484.948},"path":"audits[first-contentful-paint].displayValue"},{"values":{"timeInMs":3473.8365000000003},"path":"audits[first-meaningful-paint].displayValue"},{"values":{"timeInMs":4868.80627679871},"path":"audits[speed-index].displayValue"},{"values":{"timeInMs":5617.4839999999995},"path":"audits[first-cpu-idle].displayValue"},{"values":{"timeInMs":6774.141},"path":"audits.interactive.displayValue"},{"values":{"timeInMs":2900.6039999999975},"path":"audits[mainthread-work-breakdown].displayValue"},{"values":{"timeInMs":1186.9880000000005},"path":"audits[bootup-time].displayValue"}],"lighthouse-core/audits/metrics/first-meaningful-paint.js | title":["audits[first-meaningful-paint].title"],"lighthouse-core/audits/metrics/first-meaningful-paint.js | description":["audits[first-meaningful-paint].description"],"lighthouse-core/audits/load-fast-enough-for-pwa.js | title":["audits[load-fast-enough-for-pwa].title"],"lighthouse-core/audits/load-fast-enough-for-pwa.js | description":["audits[load-fast-enough-for-pwa].description"],"lighthouse-core/audits/metrics/speed-index.js | title":["audits[speed-index].title"],"lighthouse-core/audits/metrics/speed-index.js | description":["audits[speed-index].description"],"lighthouse-core/audits/metrics/estimated-input-latency.js | title":["audits[estimated-input-latency].title"],"lighthouse-core/audits/metrics/estimated-input-latency.js | description":["audits[estimated-input-latency].description"],"lighthouse-core/lib/i18n/i18n.js | ms":[{"values":{"timeInMs":34},"path":"audits[estimated-input-latency].displayValue"},{"values":{"timeInMs":395.5},"path":"audits[total-blocking-time].displayValue"},{"values":{"timeInMs":247},"path":"audits[max-potential-fid].displayValue"},{"values":{"timeInMs":30.134},"path":"audits[network-rtt].displayValue"},{"values":{"timeInMs":75.54599999999999},"path":"audits[network-server-latency].displayValue"}],"lighthouse-core/audits/metrics/total-blocking-time.js | title":["audits[total-blocking-time].title"],"lighthouse-core/audits/metrics/total-blocking-time.js | description":["audits[total-blocking-time].description"],"lighthouse-core/audits/metrics/max-potential-fid.js | title":["audits[max-potential-fid].title"],"lighthouse-core/audits/metrics/max-potential-fid.js | description":["audits[max-potential-fid].description"],"lighthouse-core/audits/errors-in-console.js | failureTitle":["audits[errors-in-console].title"],"lighthouse-core/audits/errors-in-console.js | description":["audits[errors-in-console].description"],"lighthouse-core/lib/i18n/i18n.js | columnURL":["audits[errors-in-console].details.headings[0].text","audits[bootup-time].details.headings[0].text","audits[uses-rel-preconnect].details.headings[0].label","audits[font-display].details.headings[0].text","audits[network-rtt].details.headings[0].text","audits[network-server-latency].details.headings[0].text","audits[uses-long-cache-ttl].details.headings[0].text","audits[total-byte-weight].details.headings[0].text","audits[offscreen-images].details.headings[1].label","audits[unminified-javascript].details.headings[0].label","audits[unused-css-rules].details.headings[0].label","audits[uses-webp-images].details.headings[1].label","audits[uses-optimized-images].details.headings[1].label","audits[uses-text-compression].details.headings[0].label","audits[uses-responsive-images].details.headings[1].label","audits[external-anchors-use-rel-noopener].details.headings[0].text","audits[uses-http2].details.headings[0].text"],"lighthouse-core/audits/errors-in-console.js | columnDesc":["audits[errors-in-console].details.headings[1].text"],"lighthouse-core/audits/time-to-first-byte.js | title":["audits[time-to-first-byte].title"],"lighthouse-core/audits/time-to-first-byte.js | description":["audits[time-to-first-byte].description"],"lighthouse-core/audits/time-to-first-byte.js | displayValue":[{"values":{"timeInMs":114.52599999999995},"path":"audits[time-to-first-byte].displayValue"}],"lighthouse-core/audits/metrics/first-cpu-idle.js | title":["audits[first-cpu-idle].title"],"lighthouse-core/audits/metrics/first-cpu-idle.js | description":["audits[first-cpu-idle].description"],"lighthouse-core/audits/metrics/interactive.js | title":["audits.interactive.title"],"lighthouse-core/audits/metrics/interactive.js | description":["audits.interactive.description"],"lighthouse-core/audits/user-timings.js | title":["audits[user-timings].title"],"lighthouse-core/audits/user-timings.js | description":["audits[user-timings].description"],"lighthouse-core/audits/critical-request-chains.js | title":["audits[critical-request-chains].title"],"lighthouse-core/audits/critical-request-chains.js | description":["audits[critical-request-chains].description"],"lighthouse-core/audits/critical-request-chains.js | displayValue":[{"values":{"itemCount":2},"path":"audits[critical-request-chains].displayValue"}],"lighthouse-core/audits/redirects.js | title":["audits.redirects.title"],"lighthouse-core/audits/redirects.js | description":["audits.redirects.description"],"lighthouse-core/audits/installable-manifest.js | failureTitle":["audits[installable-manifest].title"],"lighthouse-core/audits/installable-manifest.js | description":["audits[installable-manifest].description"],"lighthouse-core/audits/apple-touch-icon.js | title":["audits[apple-touch-icon].title"],"lighthouse-core/audits/apple-touch-icon.js | description":["audits[apple-touch-icon].description"],"lighthouse-core/audits/apple-touch-icon.js | precomposedWarning":["audits[apple-touch-icon].warnings[0]"],"lighthouse-core/audits/splash-screen.js | failureTitle":["audits[splash-screen].title"],"lighthouse-core/audits/splash-screen.js | description":["audits[splash-screen].description"],"lighthouse-core/audits/themed-omnibox.js | failureTitle":["audits[themed-omnibox].title"],"lighthouse-core/audits/themed-omnibox.js | description":["audits[themed-omnibox].description"],"lighthouse-core/audits/content-width.js | title":["audits[content-width].title"],"lighthouse-core/audits/content-width.js | description":["audits[content-width].description"],"lighthouse-core/audits/image-aspect-ratio.js | title":["audits[image-aspect-ratio].title"],"lighthouse-core/audits/image-aspect-ratio.js | description":["audits[image-aspect-ratio].description"],"lighthouse-core/audits/deprecations.js | title":["audits.deprecations.title"],"lighthouse-core/audits/deprecations.js | description":["audits.deprecations.description"],"lighthouse-core/audits/mainthread-work-breakdown.js | failureTitle":["audits[mainthread-work-breakdown].title"],"lighthouse-core/audits/mainthread-work-breakdown.js | description":["audits[mainthread-work-breakdown].description"],"lighthouse-core/audits/mainthread-work-breakdown.js | columnCategory":["audits[mainthread-work-breakdown].details.headings[0].text"],"lighthouse-core/lib/i18n/i18n.js | columnTimeSpent":["audits[mainthread-work-breakdown].details.headings[1].text","audits[network-rtt].details.headings[1].text","audits[network-server-latency].details.headings[1].text"],"lighthouse-core/audits/bootup-time.js | title":["audits[bootup-time].title"],"lighthouse-core/audits/bootup-time.js | description":["audits[bootup-time].description"],"lighthouse-core/audits/bootup-time.js | columnTotal":["audits[bootup-time].details.headings[1].text"],"lighthouse-core/audits/bootup-time.js | columnScriptEval":["audits[bootup-time].details.headings[2].text"],"lighthouse-core/audits/bootup-time.js | columnScriptParse":["audits[bootup-time].details.headings[3].text"],"lighthouse-core/audits/uses-rel-preload.js | title":["audits[uses-rel-preload].title"],"lighthouse-core/audits/uses-rel-preload.js | description":["audits[uses-rel-preload].description"],"lighthouse-core/audits/uses-rel-preconnect.js | title":["audits[uses-rel-preconnect].title"],"lighthouse-core/audits/uses-rel-preconnect.js | description":["audits[uses-rel-preconnect].description"],"lighthouse-core/lib/i18n/i18n.js | displayValueMsSavings":[{"values":{"wastedMs":342.126},"path":"audits[uses-rel-preconnect].displayValue"}],"lighthouse-core/lib/i18n/i18n.js | columnWastedBytes":["audits[uses-rel-preconnect].details.headings[1].label","audits[font-display].details.headings[1].text","audits[offscreen-images].details.headings[3].label","audits[unminified-javascript].details.headings[2].label","audits[unused-css-rules].details.headings[2].label","audits[uses-webp-images].details.headings[3].label","audits[uses-optimized-images].details.headings[3].label","audits[uses-text-compression].details.headings[2].label","audits[uses-responsive-images].details.headings[3].label"],"lighthouse-core/audits/font-display.js | failureTitle":["audits[font-display].title"],"lighthouse-core/audits/font-display.js | description":["audits[font-display].description"],"lighthouse-core/audits/network-rtt.js | title":["audits[network-rtt].title"],"lighthouse-core/audits/network-rtt.js | description":["audits[network-rtt].description"],"lighthouse-core/audits/network-server-latency.js | title":["audits[network-server-latency].title"],"lighthouse-core/audits/network-server-latency.js | description":["audits[network-server-latency].description"],"lighthouse-core/audits/offline-start-url.js | failureTitle":["audits[offline-start-url].title"],"lighthouse-core/audits/offline-start-url.js | description":["audits[offline-start-url].description"],"lighthouse-core/audits/performance-budget.js | title":["audits[performance-budget].title"],"lighthouse-core/audits/performance-budget.js | description":["audits[performance-budget].description"],"lighthouse-core/audits/resource-summary.js | title":["audits[resource-summary].title"],"lighthouse-core/audits/resource-summary.js | description":["audits[resource-summary].description"],"lighthouse-core/audits/resource-summary.js | displayValue":[{"values":{"requestCount":99,"byteCount":974958},"path":"audits[resource-summary].displayValue"}],"lighthouse-core/lib/i18n/i18n.js | columnResourceType":["audits[resource-summary].details.headings[0].text"],"lighthouse-core/lib/i18n/i18n.js | columnRequests":["audits[resource-summary].details.headings[1].text"],"lighthouse-core/lib/i18n/i18n.js | columnTransferSize":["audits[resource-summary].details.headings[2].text"],"lighthouse-core/lib/i18n/i18n.js | totalResourceType":["audits[resource-summary].details.items[0].label"],"lighthouse-core/lib/i18n/i18n.js | imageResourceType":["audits[resource-summary].details.items[1].label"],"lighthouse-core/lib/i18n/i18n.js | scriptResourceType":["audits[resource-summary].details.items[2].label"],"lighthouse-core/lib/i18n/i18n.js | documentResourceType":["audits[resource-summary].details.items[3].label"],"lighthouse-core/lib/i18n/i18n.js | fontResourceType":["audits[resource-summary].details.items[4].label"],"lighthouse-core/lib/i18n/i18n.js | otherResourceType":["audits[resource-summary].details.items[5].label"],"lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType":["audits[resource-summary].details.items[6].label"],"lighthouse-core/lib/i18n/i18n.js | mediaResourceType":["audits[resource-summary].details.items[7].label"],"lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType":["audits[resource-summary].details.items[8].label"],"lighthouse-core/audits/third-party-summary.js | title":["audits[third-party-summary].title"],"lighthouse-core/audits/third-party-summary.js | description":["audits[third-party-summary].description"],"lighthouse-core/audits/third-party-summary.js | displayValue":[{"values":{"timeInMs":48.848},"path":"audits[third-party-summary].displayValue"}],"lighthouse-core/audits/third-party-summary.js | columnThirdParty":["audits[third-party-summary].details.headings[0].text"],"lighthouse-core/lib/i18n/i18n.js | columnSize":["audits[third-party-summary].details.headings[1].text","audits[uses-long-cache-ttl].details.headings[2].text","audits[total-byte-weight].details.headings[1].text","audits[offscreen-images].details.headings[2].label","audits[unminified-javascript].details.headings[1].label","audits[unused-css-rules].details.headings[1].label","audits[uses-webp-images].details.headings[2].label","audits[uses-optimized-images].details.headings[2].label","audits[uses-text-compression].details.headings[1].label","audits[uses-responsive-images].details.headings[2].label","audits[tap-targets].details.headings[1].text"],"lighthouse-core/audits/third-party-summary.js | columnBlockingTime":["audits[third-party-summary].details.headings[2].text"],"lighthouse-core/audits/manual/pwa-cross-browser.js | title":["audits[pwa-cross-browser].title"],"lighthouse-core/audits/manual/pwa-cross-browser.js | description":["audits[pwa-cross-browser].description"],"lighthouse-core/audits/manual/pwa-page-transitions.js | title":["audits[pwa-page-transitions].title"],"lighthouse-core/audits/manual/pwa-page-transitions.js | description":["audits[pwa-page-transitions].description"],"lighthouse-core/audits/manual/pwa-each-page-has-url.js | title":["audits[pwa-each-page-has-url].title"],"lighthouse-core/audits/manual/pwa-each-page-has-url.js | description":["audits[pwa-each-page-has-url].description"],"lighthouse-core/audits/accessibility/accesskeys.js | title":["audits.accesskeys.title"],"lighthouse-core/audits/accessibility/accesskeys.js | description":["audits.accesskeys.description"],"lighthouse-core/audits/accessibility/aria-allowed-attr.js | title":["audits[aria-allowed-attr].title"],"lighthouse-core/audits/accessibility/aria-allowed-attr.js | description":["audits[aria-allowed-attr].description"],"lighthouse-core/audits/accessibility/aria-required-attr.js | title":["audits[aria-required-attr].title"],"lighthouse-core/audits/accessibility/aria-required-attr.js | description":["audits[aria-required-attr].description"],"lighthouse-core/audits/accessibility/aria-required-children.js | title":["audits[aria-required-children].title"],"lighthouse-core/audits/accessibility/aria-required-children.js | description":["audits[aria-required-children].description"],"lighthouse-core/audits/accessibility/aria-required-parent.js | title":["audits[aria-required-parent].title"],"lighthouse-core/audits/accessibility/aria-required-parent.js | description":["audits[aria-required-parent].description"],"lighthouse-core/audits/accessibility/aria-roles.js | title":["audits[aria-roles].title"],"lighthouse-core/audits/accessibility/aria-roles.js | description":["audits[aria-roles].description"],"lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title":["audits[aria-valid-attr-value].title"],"lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description":["audits[aria-valid-attr-value].description"],"lighthouse-core/audits/accessibility/aria-valid-attr.js | title":["audits[aria-valid-attr].title"],"lighthouse-core/audits/accessibility/aria-valid-attr.js | description":["audits[aria-valid-attr].description"],"lighthouse-core/audits/accessibility/audio-caption.js | title":["audits[audio-caption].title"],"lighthouse-core/audits/accessibility/audio-caption.js | description":["audits[audio-caption].description"],"lighthouse-core/audits/accessibility/button-name.js | title":["audits[button-name].title"],"lighthouse-core/audits/accessibility/button-name.js | description":["audits[button-name].description"],"lighthouse-core/audits/accessibility/bypass.js | failureTitle":["audits.bypass.title"],"lighthouse-core/audits/accessibility/bypass.js | description":["audits.bypass.description"],"lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader":["audits.bypass.details.headings[0].text","audits[color-contrast].details.headings[0].text","audits[html-has-lang].details.headings[0].text","audits[image-alt].details.headings[0].text","audits.label.details.headings[0].text","audits[link-name].details.headings[0].text","audits[meta-viewport].details.headings[0].text"],"lighthouse-core/audits/accessibility/color-contrast.js | failureTitle":["audits[color-contrast].title"],"lighthouse-core/audits/accessibility/color-contrast.js | description":["audits[color-contrast].description"],"lighthouse-core/audits/accessibility/definition-list.js | title":["audits[definition-list].title"],"lighthouse-core/audits/accessibility/definition-list.js | description":["audits[definition-list].description"],"lighthouse-core/audits/accessibility/dlitem.js | title":["audits.dlitem.title"],"lighthouse-core/audits/accessibility/dlitem.js | description":["audits.dlitem.description"],"lighthouse-core/audits/accessibility/document-title.js | title":["audits[document-title].title"],"lighthouse-core/audits/accessibility/document-title.js | description":["audits[document-title].description"],"lighthouse-core/audits/accessibility/duplicate-id.js | title":["audits[duplicate-id].title"],"lighthouse-core/audits/accessibility/duplicate-id.js | description":["audits[duplicate-id].description"],"lighthouse-core/audits/accessibility/frame-title.js | title":["audits[frame-title].title"],"lighthouse-core/audits/accessibility/frame-title.js | description":["audits[frame-title].description"],"lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle":["audits[html-has-lang].title"],"lighthouse-core/audits/accessibility/html-has-lang.js | description":["audits[html-has-lang].description"],"lighthouse-core/audits/accessibility/html-lang-valid.js | title":["audits[html-lang-valid].title"],"lighthouse-core/audits/accessibility/html-lang-valid.js | description":["audits[html-lang-valid].description"],"lighthouse-core/audits/accessibility/image-alt.js | failureTitle":["audits[image-alt].title"],"lighthouse-core/audits/accessibility/image-alt.js | description":["audits[image-alt].description"],"lighthouse-core/audits/accessibility/input-image-alt.js | title":["audits[input-image-alt].title"],"lighthouse-core/audits/accessibility/input-image-alt.js | description":["audits[input-image-alt].description"],"lighthouse-core/audits/accessibility/label.js | failureTitle":["audits.label.title"],"lighthouse-core/audits/accessibility/label.js | description":["audits.label.description"],"lighthouse-core/audits/accessibility/layout-table.js | title":["audits[layout-table].title"],"lighthouse-core/audits/accessibility/layout-table.js | description":["audits[layout-table].description"],"lighthouse-core/audits/accessibility/link-name.js | failureTitle":["audits[link-name].title"],"lighthouse-core/audits/accessibility/link-name.js | description":["audits[link-name].description"],"lighthouse-core/audits/accessibility/list.js | title":["audits.list.title"],"lighthouse-core/audits/accessibility/list.js | description":["audits.list.description"],"lighthouse-core/audits/accessibility/listitem.js | title":["audits.listitem.title"],"lighthouse-core/audits/accessibility/listitem.js | description":["audits.listitem.description"],"lighthouse-core/audits/accessibility/meta-refresh.js | title":["audits[meta-refresh].title"],"lighthouse-core/audits/accessibility/meta-refresh.js | description":["audits[meta-refresh].description"],"lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle":["audits[meta-viewport].title"],"lighthouse-core/audits/accessibility/meta-viewport.js | description":["audits[meta-viewport].description"],"lighthouse-core/audits/accessibility/object-alt.js | title":["audits[object-alt].title"],"lighthouse-core/audits/accessibility/object-alt.js | description":["audits[object-alt].description"],"lighthouse-core/audits/accessibility/tabindex.js | title":["audits.tabindex.title"],"lighthouse-core/audits/accessibility/tabindex.js | description":["audits.tabindex.description"],"lighthouse-core/audits/accessibility/td-headers-attr.js | title":["audits[td-headers-attr].title"],"lighthouse-core/audits/accessibility/td-headers-attr.js | description":["audits[td-headers-attr].description"],"lighthouse-core/audits/accessibility/th-has-data-cells.js | title":["audits[th-has-data-cells].title"],"lighthouse-core/audits/accessibility/th-has-data-cells.js | description":["audits[th-has-data-cells].description"],"lighthouse-core/audits/accessibility/valid-lang.js | title":["audits[valid-lang].title"],"lighthouse-core/audits/accessibility/valid-lang.js | description":["audits[valid-lang].description"],"lighthouse-core/audits/accessibility/video-caption.js | title":["audits[video-caption].title"],"lighthouse-core/audits/accessibility/video-caption.js | description":["audits[video-caption].description"],"lighthouse-core/audits/accessibility/video-description.js | title":["audits[video-description].title"],"lighthouse-core/audits/accessibility/video-description.js | description":["audits[video-description].description"],"lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | failureTitle":["audits[uses-long-cache-ttl].title"],"lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description":["audits[uses-long-cache-ttl].description"],"lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue":[{"values":{"itemCount":66},"path":"audits[uses-long-cache-ttl].displayValue"}],"lighthouse-core/lib/i18n/i18n.js | columnCacheTTL":["audits[uses-long-cache-ttl].details.headings[1].text"],"lighthouse-core/audits/byte-efficiency/total-byte-weight.js | title":["audits[total-byte-weight].title"],"lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description":["audits[total-byte-weight].description"],"lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue":[{"values":{"totalBytes":974958},"path":"audits[total-byte-weight].displayValue"}],"lighthouse-core/audits/byte-efficiency/offscreen-images.js | title":["audits[offscreen-images].title"],"lighthouse-core/audits/byte-efficiency/offscreen-images.js | description":["audits[offscreen-images].description"],"lighthouse-core/lib/i18n/i18n.js | displayValueByteSavings":[{"values":{"wastedBytes":91187},"path":"audits[offscreen-images].displayValue"},{"values":{"wastedBytes":12098},"path":"audits[unminified-javascript].displayValue"},{"values":{"wastedBytes":24976},"path":"audits[unused-css-rules].displayValue"},{"values":{"wastedBytes":193406},"path":"audits[uses-webp-images].displayValue"},{"values":{"wastedBytes":103177},"path":"audits[uses-optimized-images].displayValue"},{"values":{"wastedBytes":2534},"path":"audits[uses-text-compression].displayValue"},{"values":{"wastedBytes":16202},"path":"audits[uses-responsive-images].displayValue"}],"lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title":["audits[render-blocking-resources].title"],"lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description":["audits[render-blocking-resources].description"],"lighthouse-core/audits/byte-efficiency/unminified-css.js | title":["audits[unminified-css].title"],"lighthouse-core/audits/byte-efficiency/unminified-css.js | description":["audits[unminified-css].description"],"lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title":["audits[unminified-javascript].title"],"lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description":["audits[unminified-javascript].description"],"lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title":["audits[unused-css-rules].title"],"lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description":["audits[unused-css-rules].description"],"lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title":["audits[uses-webp-images].title"],"lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description":["audits[uses-webp-images].description"],"lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title":["audits[uses-optimized-images].title"],"lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description":["audits[uses-optimized-images].description"],"lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title":["audits[uses-text-compression].title"],"lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description":["audits[uses-text-compression].description"],"lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title":["audits[uses-responsive-images].title"],"lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description":["audits[uses-responsive-images].description"],"lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title":["audits[efficient-animated-content].title"],"lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description":["audits[efficient-animated-content].description"],"lighthouse-core/audits/dobetterweb/appcache-manifest.js | title":["audits[appcache-manifest].title"],"lighthouse-core/audits/dobetterweb/appcache-manifest.js | description":["audits[appcache-manifest].description"],"lighthouse-core/audits/dobetterweb/doctype.js | title":["audits.doctype.title"],"lighthouse-core/audits/dobetterweb/doctype.js | description":["audits.doctype.description"],"lighthouse-core/audits/dobetterweb/dom-size.js | title":["audits[dom-size].title"],"lighthouse-core/audits/dobetterweb/dom-size.js | description":["audits[dom-size].description"],"lighthouse-core/audits/dobetterweb/dom-size.js | displayValue":[{"values":{"itemCount":441},"path":"audits[dom-size].displayValue"}],"lighthouse-core/audits/dobetterweb/dom-size.js | columnStatistic":["audits[dom-size].details.headings[0].text"],"lighthouse-core/audits/dobetterweb/dom-size.js | columnElement":["audits[dom-size].details.headings[1].text"],"lighthouse-core/audits/dobetterweb/dom-size.js | columnValue":["audits[dom-size].details.headings[2].text"],"lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMElements":["audits[dom-size].details.items[0].statistic"],"lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMDepth":["audits[dom-size].details.items[1].statistic"],"lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMWidth":["audits[dom-size].details.items[2].statistic"],"lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | failureTitle":["audits[external-anchors-use-rel-noopener].title"],"lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | description":["audits[external-anchors-use-rel-noopener].description"],"lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | columnTarget":["audits[external-anchors-use-rel-noopener].details.headings[1].text"],"lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | columnRel":["audits[external-anchors-use-rel-noopener].details.headings[2].text"],"lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title":["audits[geolocation-on-start].title"],"lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description":["audits[geolocation-on-start].description"],"lighthouse-core/audits/dobetterweb/no-document-write.js | title":["audits[no-document-write].title"],"lighthouse-core/audits/dobetterweb/no-document-write.js | description":["audits[no-document-write].description"],"lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | title":["audits[no-vulnerable-libraries].title"],"lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | description":["audits[no-vulnerable-libraries].description"],"lighthouse-core/audits/dobetterweb/js-libraries.js | title":["audits[js-libraries].title"],"lighthouse-core/audits/dobetterweb/js-libraries.js | description":["audits[js-libraries].description"],"lighthouse-core/lib/i18n/i18n.js | columnName":["audits[js-libraries].details.headings[0].text"],"lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion":["audits[js-libraries].details.headings[1].text"],"lighthouse-core/audits/dobetterweb/notification-on-start.js | title":["audits[notification-on-start].title"],"lighthouse-core/audits/dobetterweb/notification-on-start.js | description":["audits[notification-on-start].description"],"lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | title":["audits[password-inputs-can-be-pasted-into].title"],"lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description":["audits[password-inputs-can-be-pasted-into].description"],"lighthouse-core/audits/dobetterweb/uses-http2.js | failureTitle":["audits[uses-http2].title"],"lighthouse-core/audits/dobetterweb/uses-http2.js | description":["audits[uses-http2].description"],"lighthouse-core/audits/dobetterweb/uses-http2.js | displayValue":[{"values":{"itemCount":2},"path":"audits[uses-http2].displayValue"}],"lighthouse-core/audits/dobetterweb/uses-http2.js | columnProtocol":["audits[uses-http2].details.headings[1].text"],"lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title":["audits[uses-passive-event-listeners].title"],"lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | description":["audits[uses-passive-event-listeners].description"],"lighthouse-core/audits/seo/meta-description.js | failureTitle":["audits[meta-description].title"],"lighthouse-core/audits/seo/meta-description.js | description":["audits[meta-description].description"],"lighthouse-core/audits/seo/http-status-code.js | title":["audits[http-status-code].title"],"lighthouse-core/audits/seo/http-status-code.js | description":["audits[http-status-code].description"],"lighthouse-core/audits/seo/font-size.js | title":["audits[font-size].title"],"lighthouse-core/audits/seo/font-size.js | description":["audits[font-size].description"],"lighthouse-core/audits/seo/font-size.js | displayValue":[{"values":{"decimalProportion":0.9980271556226065},"path":"audits[font-size].displayValue"}],"lighthouse-core/audits/seo/link-text.js | title":["audits[link-text].title"],"lighthouse-core/audits/seo/link-text.js | description":["audits[link-text].description"],"lighthouse-core/audits/seo/is-crawlable.js | failureTitle":["audits[is-crawlable].title"],"lighthouse-core/audits/seo/is-crawlable.js | description":["audits[is-crawlable].description"],"lighthouse-core/audits/seo/robots-txt.js | title":["audits[robots-txt].title"],"lighthouse-core/audits/seo/robots-txt.js | description":["audits[robots-txt].description"],"lighthouse-core/audits/seo/tap-targets.js | failureTitle":["audits[tap-targets].title"],"lighthouse-core/audits/seo/tap-targets.js | description":["audits[tap-targets].description"],"lighthouse-core/audits/seo/tap-targets.js | displayValue":[{"values":{"decimalProportion":0.8125},"path":"audits[tap-targets].displayValue"}],"lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader":["audits[tap-targets].details.headings[0].text"],"lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader":["audits[tap-targets].details.headings[2].text"],"lighthouse-core/audits/seo/hreflang.js | title":["audits.hreflang.title"],"lighthouse-core/audits/seo/hreflang.js | description":["audits.hreflang.description"],"lighthouse-core/audits/seo/plugins.js | title":["audits.plugins.title"],"lighthouse-core/audits/seo/plugins.js | description":["audits.plugins.description"],"lighthouse-core/audits/seo/canonical.js | title":["audits.canonical.title"],"lighthouse-core/audits/seo/canonical.js | description":["audits.canonical.description"],"lighthouse-core/audits/seo/manual/structured-data.js | title":["audits[structured-data].title"],"lighthouse-core/audits/seo/manual/structured-data.js | description":["audits[structured-data].description"],"lighthouse-core/config/default-config.js | performanceCategoryTitle":["categories.performance.title"],"lighthouse-core/config/default-config.js | a11yCategoryTitle":["categories.accessibility.title"],"lighthouse-core/config/default-config.js | a11yCategoryDescription":["categories.accessibility.description"],"lighthouse-core/config/default-config.js | a11yCategoryManualDescription":["categories.accessibility.manualDescription"],"lighthouse-core/config/default-config.js | bestPracticesCategoryTitle":["categories[best-practices].title"],"lighthouse-core/config/default-config.js | seoCategoryTitle":["categories.seo.title"],"lighthouse-core/config/default-config.js | seoCategoryDescription":["categories.seo.description"],"lighthouse-core/config/default-config.js | seoCategoryManualDescription":["categories.seo.manualDescription"],"lighthouse-core/config/default-config.js | pwaCategoryTitle":["categories.pwa.title"],"lighthouse-core/config/default-config.js | pwaCategoryDescription":["categories.pwa.description"],"lighthouse-core/config/default-config.js | pwaCategoryManualDescription":["categories.pwa.manualDescription"],"lighthouse-core/config/default-config.js | metricGroupTitle":["categoryGroups.metrics.title"],"lighthouse-core/config/default-config.js | loadOpportunitiesGroupTitle":["categoryGroups[load-opportunities].title"],"lighthouse-core/config/default-config.js | loadOpportunitiesGroupDescription":["categoryGroups[load-opportunities].description"],"lighthouse-core/config/default-config.js | budgetsGroupTitle":["categoryGroups.budgets.title"],"lighthouse-core/config/default-config.js | budgetsGroupDescription":["categoryGroups.budgets.description"],"lighthouse-core/config/default-config.js | diagnosticsGroupTitle":["categoryGroups.diagnostics.title"],"lighthouse-core/config/default-config.js | diagnosticsGroupDescription":["categoryGroups.diagnostics.description"],"lighthouse-core/config/default-config.js | pwaFastReliableGroupTitle":["categoryGroups[pwa-fast-reliable].title"],"lighthouse-core/config/default-config.js | pwaInstallableGroupTitle":["categoryGroups[pwa-installable].title"],"lighthouse-core/config/default-config.js | pwaOptimizedGroupTitle":["categoryGroups[pwa-optimized].title"],"lighthouse-core/config/default-config.js | a11yBestPracticesGroupTitle":["categoryGroups[a11y-best-practices].title"],"lighthouse-core/config/default-config.js | a11yBestPracticesGroupDescription":["categoryGroups[a11y-best-practices].description"],"lighthouse-core/config/default-config.js | a11yColorContrastGroupTitle":["categoryGroups[a11y-color-contrast].title"],"lighthouse-core/config/default-config.js | a11yColorContrastGroupDescription":["categoryGroups[a11y-color-contrast].description"],"lighthouse-core/config/default-config.js | a11yNamesLabelsGroupTitle":["categoryGroups[a11y-names-labels].title"],"lighthouse-core/config/default-config.js | a11yNamesLabelsGroupDescription":["categoryGroups[a11y-names-labels].description"],"lighthouse-core/config/default-config.js | a11yNavigationGroupTitle":["categoryGroups[a11y-navigation].title"],"lighthouse-core/config/default-config.js | a11yNavigationGroupDescription":["categoryGroups[a11y-navigation].description"],"lighthouse-core/config/default-config.js | a11yAriaGroupTitle":["categoryGroups[a11y-aria].title"],"lighthouse-core/config/default-config.js | a11yAriaGroupDescription":["categoryGroups[a11y-aria].description"],"lighthouse-core/config/default-config.js | a11yLanguageGroupTitle":["categoryGroups[a11y-language].title"],"lighthouse-core/config/default-config.js | a11yLanguageGroupDescription":["categoryGroups[a11y-language].description"],"lighthouse-core/config/default-config.js | a11yAudioVideoGroupTitle":["categoryGroups[a11y-audio-video].title"],"lighthouse-core/config/default-config.js | a11yAudioVideoGroupDescription":["categoryGroups[a11y-audio-video].description"],"lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupTitle":["categoryGroups[a11y-tables-lists].title"],"lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupDescription":["categoryGroups[a11y-tables-lists].description"],"lighthouse-core/config/default-config.js | seoMobileGroupTitle":["categoryGroups[seo-mobile].title"],"lighthouse-core/config/default-config.js | seoMobileGroupDescription":["categoryGroups[seo-mobile].description"],"lighthouse-core/config/default-config.js | seoContentGroupTitle":["categoryGroups[seo-content].title"],"lighthouse-core/config/default-config.js | seoContentGroupDescription":["categoryGroups[seo-content].description"],"lighthouse-core/config/default-config.js | seoCrawlingGroupTitle":["categoryGroups[seo-crawl].title"],"lighthouse-core/config/default-config.js | seoCrawlingGroupDescription":["categoryGroups[seo-crawl].description"]}},"stackPacks":[]};</script>
  <script>
    function __initLighthouseReport__() {
      const dom = new DOM(document);
      const renderer = new ReportRenderer(dom);

      const container = document.querySelector('main');
      renderer.renderReport(window.__LIGHTHOUSE_JSON__, container);

      // Hook in JS features and page-level event listeners after the report
      // is in the document.
      const features = new ReportUIFeatures(dom);
      features.initFeatures(window.__LIGHTHOUSE_JSON__);
    }
    window.addEventListener('DOMContentLoaded', __initLighthouseReport__);

    document.addEventListener('lh-analytics', e => {
      if (window.ga) {
        ga(e.detail.cmd, e.detail.fields);
      }
    });

    document.addEventListener('lh-log', e => {
      const logger = new Logger(document.querySelector('#lh-log'));

      switch (e.detail.cmd) {
        case 'log':
          logger.log(e.detail.msg);
          break;
        case 'warn':
          logger.warn(e.detail.msg);
          break;
        case 'error':
          logger.error(e.detail.msg);
          break;
        case 'hide':
          logger.hide();
          break;
      }
    });
  </script>
</body>
</html>
